debuginfo.c revision c5af2ae7cec426721577d4a249d4a7b7c0eeb65e
1eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 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" 356c591e15c1d6402a2a755310f005f795b68e7e38sewardj#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 36eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_threadstate.h" 37b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_debuginfo.h" /* self */ 38eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_demangle.h" 39eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcbase.h" 40eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcassert.h" 41eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcprint.h" 42b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcfile.h" 4313ac96dea734b3933a73524b991ac64fb48a4d57sewardj#include "pub_core_libcproc.h" // VG_(getenv) 44d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_seqmatch.h" 45eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_options.h" 46b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo) 47eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_aspacemgr.h" 48b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC 4972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#include "pub_core_xarray.h" 50b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_oset.h" 516882443ef154bca367bc591287de641e43a9e108njn#include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency 52f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_ume.h" 53b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 54b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h" /* dinfo_zalloc/free */ 555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#include "priv_image.h" 56b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h" /* ML_(pp_GX) */ 57b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h" 58eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_storage.h" 59eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readdwarf.h" 60eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readstabs.h" 614ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_linux) 624ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readelf.h" 63b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# include "priv_readdwarf3.h" 64c8259b85b701d25d72aabe9dc0a8154517f96913sewardj# include "priv_readpdb.h" 65f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 66f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readmacho.h" 67f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readpdb.h" 684ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif 69eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 70c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 716f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj/* Set this to 1 to enable debug printing for the 726f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj should-we-load-debuginfo-now? finite state machine. */ 736f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj#define DEBUG_FSM 0 746f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 756f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 76c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 77c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*--- The _svma / _avma / _image / _bias naming scheme ---*/ 78c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 79c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 80c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/* JRS 11 Jan 07: I find the different kinds of addresses involved in 81c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj debuginfo reading confusing. Recently I arrived at some 82c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj terminology which makes it clearer (to me, at least). There are 3 83c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj kinds of address used in the debuginfo reading process: 84c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 85c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj stated VMAs - the address where (eg) a .so says a symbol is, that 86c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj is, what it tells you if you consider the .so in 87c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj isolation 88c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 89c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj actual VMAs - the address where (eg) said symbol really wound up 90c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj after the .so was mapped into memory 91c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 92c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj image addresses - pointers into the copy of the .so (etc) 93c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj transiently mmaped aboard whilst we read its info 94c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 95c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj Additionally I use the term 'bias' to denote the difference 96c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj between stated and actual VMAs for a given entity. 97c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 98c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj This terminology is not used consistently, but a start has been 99c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj made. readelf.c and the call-frame info reader in readdwarf.c now 100c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj use it. Specifically, various variables and structure fields have 101f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj been annotated with _avma / _svma / _image / _bias. In places _img 102f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj is used instead of _image for the sake of brevity. 103c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj*/ 104c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 105c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 106eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 107f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- fwdses ---*/ 108f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 109f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 11020ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippestatic UInt CF_info_generation = 0; 1115c3dba227192de63d86f65ec7d9597c132818c37philippestatic void cfsi_m_cache__invalidate ( void ); 112f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 113f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 114f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 115eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Root structure ---*/ 116eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 117eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* The root structure for the entire debug info system. It is a 119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj linked list of DebugInfos. */ 120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic DebugInfo* debugInfo_list = NULL; 121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find 'di' in the debugInfo_list and move it one step closer the the 124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj front of the list, so as to make subsequent searches for it 125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj cheaper. When used in a controlled way, makes a major improvement 126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in some DebugInfo-search-intensive situations, most notably stack 127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj unwinding on amd64-linux. */ 128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void move_DebugInfo_one_step_forward ( DebugInfo* di ) 129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo *di0, *di1, *di2; 131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == debugInfo_list) 132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; /* already at head of list */ 133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = debugInfo_list; 135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = NULL; 136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = NULL; 137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 == NULL || di0 == di) break; 139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = di1; 140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = di0; 141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = di0->next; 142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di0 == di); 144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 != NULL) { 145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* tmp; 146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* di0 points to di, di1 to its predecessor, and di2 to di1's 147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj predecessor. Swap di0 and di1, that is, move di0 one step 148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj closer to the start of the list. */ 149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2->next == di1); 150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tmp = di0->next; 152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->next = di0; 153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = tmp; 155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 == NULL) { 158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* it's second in the list. */ 159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(debugInfo_list == di1); 160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = di0->next; 162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di0; 164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 168eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 169eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Notification (acquire/discard) helpers ---*/ 170eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 171eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Gives out unique abstract handles for allocated DebugInfos. See 1739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj comment in priv_storage.h, declaration of struct _DebugInfo, for 1749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj details. */ 1759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic ULong handle_counter = 1; 1769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Allocate and zero out a new DebugInfo record. */ 178eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 1791636d33c13958b9c0e7d3059cdd5005746418eb2florianDebugInfo* alloc_DebugInfo( const HChar* filename ) 180eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool traceme; 182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 183eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 184f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj vg_assert(filename); 185f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 1869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo)); 187a5acac39bf3be7546222b1316faee5ee524be0d1sewardj di->handle = handle_counter++; 188a5acac39bf3be7546222b1316faee5ee524be0d1sewardj di->fsm.filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename); 1896b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.maps = VG_(newXA)( 1906b5625bb609b154766d2e138b61e15655f60b710sewardj ML_(dinfo_zalloc), "di.debuginfo.aDI.3", 1916b5625bb609b154766d2e138b61e15655f60b710sewardj ML_(dinfo_free), sizeof(struct _DebugInfoMapping)); 192eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 193452e89a9f847975609b3ad318943830f2cce841csewardj /* Everything else -- pointers, sizes, arrays -- is zeroed by 194452e89a9f847975609b3ad318943830f2cce841csewardj ML_(dinfo_zalloc). Now set up the debugging-output flags. */ 195f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj traceme 1960f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj = VG_(string_match)( VG_(clo_trace_symtab_patt), filename ); 197f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj if (traceme) { 198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_symtab = VG_(clo_trace_symtab); 199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_cfi = VG_(clo_trace_cfi); 200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_syms = VG_(clo_debug_dump_syms); 201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_line = VG_(clo_debug_dump_line); 202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_frames = VG_(clo_debug_dump_frames); 203f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj } 204f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 206eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 207eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 208eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Free a DebugInfo, and also all the stuff hanging off it. */ 210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void free_DebugInfo ( DebugInfo* di ) 211eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 21259a2d18d0ddfa241850017252b0804d469187d79sewardj Word i, j, n; 2139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ent; 21459a2d18d0ddfa241850017252b0804d469187d79sewardj GExpr* gexpr; 215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 2176b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->fsm.maps) VG_(deleteXA)(di->fsm.maps); 218a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename); 219c5af2ae7cec426721577d4a249d4a7b7c0eeb65emjw if (di->fsm.dbgname) ML_(dinfo_free)(di->fsm.dbgname); 220f1e1aa691d7a2f0f2f933daf060bec5ae6938705philippe if (di->soname) ML_(dinfo_free)(di->soname); 221a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->loctab) ML_(dinfo_free)(di->loctab); 22259e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (di->loctab_fndn_ix) ML_(dinfo_free)(di->loctab_fndn_ix); 223a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab) ML_(dinfo_free)(di->inltab); 2245c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_base) ML_(dinfo_free)(di->cfsi_base); 2255c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_m_ix) ML_(dinfo_free)(di->cfsi_m_ix); 2265c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd) ML_(dinfo_free)(di->cfsi_rd); 2275c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_m_pool) VG_(deleteDedupPA)(di->cfsi_m_pool); 228a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs); 229a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fpo) ML_(dinfo_free)(di->fpo); 230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 231a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (di->symtab) { 232a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* We have to visit all the entries so as to free up any 233a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec_names arrays that might exist. */ 234a5cace0c2a3e212931badbf6398a0cd98393121asewardj n = di->symtab_used; 235a5cace0c2a3e212931badbf6398a0cd98393121asewardj for (i = 0; i < n; i++) { 236a5cace0c2a3e212931badbf6398a0cd98393121asewardj DiSym* sym = &di->symtab[i]; 237a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sym->sec_names) 238a5cace0c2a3e212931badbf6398a0cd98393121asewardj ML_(dinfo_free)(sym->sec_names); 239a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 240a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* and finally .. */ 241a5cace0c2a3e212931badbf6398a0cd98393121asewardj ML_(dinfo_free)(di->symtab); 242a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 243a5cace0c2a3e212931badbf6398a0cd98393121asewardj 2442352e9843d8a616b9d829aef929d218aea9b4ae0philippe if (di->strpool) 2452352e9843d8a616b9d829aef929d218aea9b4ae0philippe VG_(deleteDedupPA) (di->strpool); 24659e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (di->fndnpool) 24759e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(deleteDedupPA) (di->fndnpool); 248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Delete the two admin arrays. These lists exist primarily so 2509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj that we can visit each object exactly once when we need to 2519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj delete them. */ 2529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->admin_tyents) { 2539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n = VG_(sizeXA)(di->admin_tyents); 25459a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 2559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i); 2569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Dump anything hanging off this ent */ 2579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(TyEnt__make_EMPTY)(ent); 25859a2d18d0ddfa241850017252b0804d469187d79sewardj } 2599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(deleteXA)(di->admin_tyents); 2609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents = NULL; 261eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 26259a2d18d0ddfa241850017252b0804d469187d79sewardj 26359a2d18d0ddfa241850017252b0804d469187d79sewardj if (di->admin_gexprs) { 26459a2d18d0ddfa241850017252b0804d469187d79sewardj n = VG_(sizeXA)(di->admin_gexprs); 26559a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 26659a2d18d0ddfa241850017252b0804d469187d79sewardj gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i); 26759a2d18d0ddfa241850017252b0804d469187d79sewardj ML_(dinfo_free)(gexpr); 26859a2d18d0ddfa241850017252b0804d469187d79sewardj } 26959a2d18d0ddfa241850017252b0804d469187d79sewardj VG_(deleteXA)(di->admin_gexprs); 27059a2d18d0ddfa241850017252b0804d469187d79sewardj di->admin_gexprs = NULL; 271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump the variable info. This is kinda complex: we must take 274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj care not to free items which reside in either the admin lists 275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (as we have just freed them) or which reside in the DebugInfo's 276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj string table. */ 277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->varinfo) { 278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) { 279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i); 280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!scope) continue; 281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* iterate over all entries in 'scope' */ 282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIter)(scope); 283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange = VG_(OSetGen_Next)(scope); 285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) break; 286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* for each var in 'arange' */ 287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->vars); 288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) { 289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j); 290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var); 291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Nothing to free in var: all the pointer fields refer 292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to stuff either on an admin list, or in 2937293d2530f8c60c1060f9f003e214cc341d35266philippe .strpool */ 294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(arange->vars); 296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Don't free arange itself, as OSetGen_Destroy does 297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that */ 298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Destroy)(scope); 300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(di->varinfo); 302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(di); 305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* 'si' is a member of debugInfo_list. Find it, remove it from the 309eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj list, notify m_redir that this has happened, and free all storage 310eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj reachable from it. 311eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfo ( DebugInfo* di ) 313eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3146bd9dc18c043927c1196caba20a327238a179c42florian const HChar* reason = "munmap"; 3154ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo** prev_next_ptr = &debugInfo_list; 317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr = debugInfo_list; 318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (curr) { 320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr == di) { 321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Found it; remove from list and free it. */ 32233e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo 32333e4e7eaab263cea956700f56f007ab26c39eab4sewardj && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))) 324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 325738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Discarding syms at %#lx-%#lx in %s due to %s()\n", 326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma, 327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma + di->text_size, 328a5acac39bf3be7546222b1316faee5ee524be0d1sewardj curr->fsm.filename ? curr->fsm.filename 3291636d33c13958b9c0e7d3059cdd5005746418eb2florian : "???", 3304ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj reason); 331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(*prev_next_ptr == curr); 332eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *prev_next_ptr = curr->next; 33333e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo) 33433e4e7eaab263cea956700f56f007ab26c39eab4sewardj VG_(redir_notify_delete_DebugInfo)( curr ); 335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj free_DebugInfo(curr); 336eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 337eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 338eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj prev_next_ptr = &curr->next; 339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 340eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 341eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Not found. */ 343eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 344eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 345eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Repeatedly scan debugInfo_list, looking for DebugInfos with text 347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj AVMAs intersecting [start,start+length), and call discard_DebugInfo 348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to get rid of them. This modifies the list, hence the multiple 349f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj iterations. Returns True iff any such DebugInfos were found. 350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 351f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Bool discard_syms_in_range ( Addr start, SizeT length ) 352eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 353f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = False; 354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 358eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = False; 359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 362eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (curr == NULL) 363eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->text_present 365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && curr->text_size > 0 366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && (start+length - 1 < curr->text_avma 367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || curr->text_avma + curr->text_size - 1 < start)) { 368eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* no overlap */ 369eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 370eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = True; 371eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 372eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 373eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 374eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 375eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 376eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!found) break; 377f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = True; 378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 379eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 380f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 381f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return anyFound; 382eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 383eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 384eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle 386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj wraparound at the end of the address space -- just asserts in that 387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case. */ 388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 ) 389eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr e1, e2; 391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (len1 == 0 || len2 == 0) 392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e1 = s1 + len1 - 1; 394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e2 = s2 + len2 - 1; 395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Assert that we don't have wraparound. If we do it would imply 396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that file sections are getting mapped around the end of the 397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address space, which sounds unlikely. */ 398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s1 <= e1); 399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s2 <= e2); 400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (e1 < s2 || e2 < s1) return False; 401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 403eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 404eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4056b5625bb609b154766d2e138b61e15655f60b710sewardj/* Do the basic mappings of the two DebugInfos overlap in any way? */ 406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 ) 407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4086b5625bb609b154766d2e138b61e15655f60b710sewardj Word i, j; 409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1); 410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2); 4116b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di1->fsm.maps); i++) { 4126b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map1 = VG_(indexXA)(di1->fsm.maps, i); 4136b5625bb609b154766d2e138b61e15655f60b710sewardj for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) { 4146b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j); 4156b5625bb609b154766d2e138b61e15655f60b710sewardj if (ranges_overlap(map1->avma, map1->size, map2->avma, map2->size)) 4166b5625bb609b154766d2e138b61e15655f60b710sewardj return True; 4176b5625bb609b154766d2e138b61e15655f60b710sewardj } 4186b5625bb609b154766d2e138b61e15655f60b710sewardj } 419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard all elements of debugInfo_list whose .mark bit is set. 425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_marked_DebugInfos ( void ) 427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) 435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->mark) 437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = curr->next; 439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) break; 442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard any elements of debugInfo_list which overlap with diRef. 4496b5625bb609b154766d2e138b61e15655f60b710sewardj Clearly diRef must have its mapping information set to something sane. */ 450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef ) 451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Mark all the DebugInfos in debugInfo_list that need to be 454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj deleted. First, clear all the mark bits; then set them if they 455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj overlap with siRef. Since siRef itself is in this list we at 456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj least expect its own mark bit to be set. */ 457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = do_DebugInfos_overlap( di, diRef ); 459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == diRef) { 460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->mark); 461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = False; 462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 463eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_marked_DebugInfos(); 465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 467eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4680f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj/* Find the existing DebugInfo for |filename| or if not found, create 4690f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj one. In the latter case |filename| is strdup'd into VG_AR_DINFO, 4700f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj and the new DebugInfo is added to debugInfo_list. */ 4711636d33c13958b9c0e7d3059cdd5005746418eb2florianstatic DebugInfo* find_or_create_DebugInfo_for ( HChar* filename ) 472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(filename); 475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 476a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.filename); 477a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (0==VG_(strcmp)(di->fsm.filename, filename)) 478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) { 4810f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj di = alloc_DebugInfo(filename); 482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->next = debugInfo_list; 484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di; 485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 487eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 488eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 489eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 490f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Debuginfo reading for 'di' has just been successfully completed. 491f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Check that the invariants stated in 492f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in 493f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h are observed. */ 494f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void check_CFSI_related_invariants ( DebugInfo* di ) 495f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 496f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di2 = NULL; 4976b5625bb609b154766d2e138b61e15655f60b710sewardj Bool has_nonempty_rx = False; 4986b5625bb609b154766d2e138b61e15655f60b710sewardj Bool cfsi_fits = False; 4996b5625bb609b154766d2e138b61e15655f60b710sewardj Word i, j; 500f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di); 501f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* This fn isn't called until after debuginfo for this object has 502f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj been successfully read. And that shouldn't happen until we have 503f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj both a r-x and rw- mapping for the object. Hence: */ 504a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.have_rx_map); 505a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.have_rw_map); 5066b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 5076b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 5086b5625bb609b154766d2e138b61e15655f60b710sewardj /* We are interested in r-x mappings only */ 5096b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map->rx) 510f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 5116b5625bb609b154766d2e138b61e15655f60b710sewardj 5126b5625bb609b154766d2e138b61e15655f60b710sewardj /* degenerate case: r-x section is empty */ 5136b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->size == 0) 514f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 5156b5625bb609b154766d2e138b61e15655f60b710sewardj has_nonempty_rx = True; 5166b5625bb609b154766d2e138b61e15655f60b710sewardj 5176b5625bb609b154766d2e138b61e15655f60b710sewardj /* normal case: r-x section is nonempty */ 5186b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (0) */ 5196b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(map->size > 0); 5206b5625bb609b154766d2e138b61e15655f60b710sewardj 5216b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (1) */ 5226b5625bb609b154766d2e138b61e15655f60b710sewardj for (di2 = debugInfo_list; di2; di2 = di2->next) { 5236b5625bb609b154766d2e138b61e15655f60b710sewardj if (di2 == di) 5246b5625bb609b154766d2e138b61e15655f60b710sewardj continue; 5256b5625bb609b154766d2e138b61e15655f60b710sewardj for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) { 5266b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j); 5276b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map2->rx || map2->size == 0) 5286b5625bb609b154766d2e138b61e15655f60b710sewardj continue; 5296b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(!ranges_overlap(map->avma, map->size, 5306b5625bb609b154766d2e138b61e15655f60b710sewardj map2->avma, map2->size)); 5316b5625bb609b154766d2e138b61e15655f60b710sewardj } 5326b5625bb609b154766d2e138b61e15655f60b710sewardj } 5336b5625bb609b154766d2e138b61e15655f60b710sewardj di2 = NULL; 5346b5625bb609b154766d2e138b61e15655f60b710sewardj 5356b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (2) */ 5365c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd) { 5376b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */ 5386b5625bb609b154766d2e138b61e15655f60b710sewardj /* Assume the csfi fits completely into one individual mapping 5396b5625bb609b154766d2e138b61e15655f60b710sewardj for now. This might need to be improved/reworked later. */ 5406b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->cfsi_minavma >= map->avma && 5416b5625bb609b154766d2e138b61e15655f60b710sewardj di->cfsi_maxavma < map->avma + map->size) 5426b5625bb609b154766d2e138b61e15655f60b710sewardj cfsi_fits = True; 5436b5625bb609b154766d2e138b61e15655f60b710sewardj } 544f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 5456b5625bb609b154766d2e138b61e15655f60b710sewardj 5466b5625bb609b154766d2e138b61e15655f60b710sewardj /* degenerate case: all r-x sections are empty */ 5476b5625bb609b154766d2e138b61e15655f60b710sewardj if (!has_nonempty_rx) { 5485c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_rd == NULL); 5496b5625bb609b154766d2e138b61e15655f60b710sewardj return; 550f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 5516b5625bb609b154766d2e138b61e15655f60b710sewardj 5526b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (2) - cont. */ 5535c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd) 5546b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(cfsi_fits); 5556b5625bb609b154766d2e138b61e15655f60b710sewardj 556f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariants (3) and (4) */ 5575c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd) { 558f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used > 0); 559f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size > 0); 560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < di->cfsi_used; i++) { 5615c3dba227192de63d86f65ec7d9597c132818c37philippe DiCfSI* cfsi = &di->cfsi_rd[i]; 562f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->len > 0); 563f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base >= di->cfsi_minavma); 564f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma); 565f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i > 0) { 5665c3dba227192de63d86f65ec7d9597c132818c37philippe DiCfSI* cfsip = &di->cfsi_rd[i-1]; 567f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsip->base + cfsip->len <= cfsi->base); 568f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 569f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 570f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 571f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used == 0); 572f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size == 0); 573f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 574f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 575f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 576f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 577f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 578f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 579f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/ 580f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 581f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 582f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 583f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid VG_(di_initialise) ( void ) 584f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 585f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* There's actually very little to do here, since everything 586f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj centers around the DebugInfos in debugInfo_list, they are 587f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj created and destroyed on demand, and each one is treated more or 588f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj less independently. */ 589f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(debugInfo_list == NULL); 590f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 591f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* flush the CFI fast query cache. */ 5925c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 593f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 594f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 595f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 5964ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5984ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/ 5994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 6004ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 6014ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 602f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VGO_linux) || defined(VGO_darwin) 603eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 604eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The debug info system is driven by notifications that a text 605731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj segment has been mapped in, or unmapped, or when sections change 606731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj permission. It's all a bit kludgey and basically means watching 607731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj syscalls, trying to second-guess when the system's dynamic linker 608731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is done with mapping in a new object for execution. This is all 609731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj tracked using the DebugInfoFSM struct for the object. Anyway, once 610731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj we finally decide we've got to an accept state, this section then 611731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj will acquire whatever info is available for the corresponding 612731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj object. This section contains the notification handlers, which 613731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj update the FSM and determine when an accept state has been reached. 614731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj*/ 615731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 616731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj/* When the sequence of observations causes a DebugInfoFSM to move 617731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj into the accept state, call here to actually get the debuginfo read 618731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj in. Returns a ULong whose purpose is described in comments 619731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj preceding VG_(di_notify_mmap) just below. 620731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj*/ 621731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardjstatic ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di ) 622731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj{ 623731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ULong di_handle; 624731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool ok; 625731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 626731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.filename); 627731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 628731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ start ELF OBJECT " 629731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "------------------------------\n"); 630731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); 631731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 632731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 633731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* We're going to read symbols and debug info for the avma 6346b5625bb609b154766d2e138b61e15655f60b710sewardj ranges specified in the _DebugInfoFsm mapping array. First 6356b5625bb609b154766d2e138b61e15655f60b710sewardj get rid of any other DebugInfos which overlap any of those 6366b5625bb609b154766d2e138b61e15655f60b710sewardj ranges (to avoid total confusion). */ 637731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj discard_DebugInfos_which_overlap_with( di ); 638731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 639731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* .. and acquire new info. */ 640731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# if defined(VGO_linux) 641731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ok = ML_(read_elf_debug_info)( di ); 642731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# elif defined(VGO_darwin) 643731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ok = ML_(read_macho_debug_info)( di ); 644731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# else 645731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# error "unknown OS" 646731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 647731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 648731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (ok) { 649731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 650731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ Canonicalising the " 651731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "acquired info ------\n"); 652731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* invalidate the CFI unwind cache. */ 6535c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 654731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* prepare read data for use */ 655731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ML_(canonicaliseTables)( di ); 6565c3dba227192de63d86f65ec7d9597c132818c37philippe /* Check invariants listed in 6575c3dba227192de63d86f65ec7d9597c132818c37philippe Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 6585c3dba227192de63d86f65ec7d9597c132818c37philippe priv_storage.h. */ 6595c3dba227192de63d86f65ec7d9597c132818c37philippe check_CFSI_related_invariants(di); 6605c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(finish_CFSI_arrays)(di); 661731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* notify m_redir about it */ 662731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ Notifying m_redir ------\n"); 663731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj VG_(redir_notify_new_DebugInfo)( di ); 664731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Note that we succeeded */ 665731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->have_dinfo = True; 666731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj tl_assert(di->handle > 0); 667731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di_handle = di->handle; 668731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 669731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } else { 670731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ ELF reading failed ------\n"); 671731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Something went wrong (eg. bad ELF file). Should we delete 672731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj this DebugInfo? No - it contains info on the rw/rx 673731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj mappings, at least. */ 674731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di_handle = 0; 675731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->have_dinfo == False); 676731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } 677731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 678731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 679731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); 680731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ end ELF OBJECT " 681731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "------------------------------\n"); 682731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 683731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 684731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return di_handle; 685731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj} 686731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 687eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Notify the debuginfo system about a new mapping. This is the way 689eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj new debug information gets loaded. If allow_SkFileV is True, it 690eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj will try load debug info if the mapping at 'a' belongs to Valgrind; 691eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas normally (False) it will not do that. This allows us to 692eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj carefully control when the thing will read symbols from the 6939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Valgrind executable itself. 6949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 6955f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj If use_fd is not -1, that is used instead of the filename; this 6965f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj avoids perturbing fcntl locks, which are released by simply 6975f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj re-opening and closing the same file (even via different fd!). 6985f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 6999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj If a call to VG_(di_notify_mmap) causes debug info to be read, then 7009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the returned ULong is an abstract handle which can later be used to 7019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj refer to the debuginfo read as a result of this specific mapping, 7029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in later queries to m_debuginfo. In this case the handle value 7039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj will be one or above. If the returned value is zero, no debug info 7049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj was read. */ 705eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7065f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardjULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) 707eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 7084ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj NSegment const * seg; 709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar* filename; 710731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool is_rx_map, is_rw_map, is_ro_map; 711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 7125f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj Int actual_fd, oflags; 7135f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj SysRes preadres; 714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar buf1k[1024]; 7156f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool debug = (DEBUG_FSM != 0); 716ec61b6509566cf36ab3968d69226cecf177cb0fesewardj SysRes statres; 717ec61b6509566cf36ab3968d69226cecf177cb0fesewardj struct vg_stat statbuf; 718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 7195f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj vg_assert(use_fd >= -1); 7205f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* In short, figure out if this mapping is of interest to us, and 722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if so, try to guess what ld.so is doing and when/if we should 723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj read debug info. */ 724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg = VG_(am_find_nsegment)(a); 725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg); 726eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7276f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) { 7286f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-0:\n"); 729a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n", 730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->start, seg->end, 731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasR ? 'r' : '-', 732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' ); 7336f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 734eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* guaranteed by aspacemgr-linux.c, sane_NSegment() */ 736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg->end > seg->start); 737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ignore non-file mappings */ 739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( ! (seg->kind == SkFileC 740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (seg->kind == SkFileV && allow_SkFileV)) ) 7419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If the file doesn't have a name, we're hosed. Give up. */ 7443e7986312a0ffc7646b0552d4c4ea3744a870e73florian filename = VG_(am_get_filename)( seg ); 745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!filename) 7469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 7480ab84fe82d1e25c2e0544d08826df42caa44ded1bart /* 7490ab84fe82d1e25c2e0544d08826df42caa44ded1bart * Cannot read from these magic files: 7500ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- WARNING: Serious error when reading debug info 7510ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- When reading debug info from /proc/xen/privcmd: 7520ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- can't read file to inspect ELF header 7530ab84fe82d1e25c2e0544d08826df42caa44ded1bart */ 7540ab84fe82d1e25c2e0544d08826df42caa44ded1bart if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0) 7550ab84fe82d1e25c2e0544d08826df42caa44ded1bart return 0; 7560ab84fe82d1e25c2e0544d08826df42caa44ded1bart 757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-2: %s\n", filename); 759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 760ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Only try to read debug information from regular files. */ 76115728ab41ea41bf731dcc74ac68354550ced2189bart statres = VG_(stat)(filename, &statbuf); 762ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 763ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* stat dereferences symlinks, so we don't expect it to succeed and 764ec61b6509566cf36ab3968d69226cecf177cb0fesewardj yet produce something that is a symlink. */ 7659c20ece00e07304f66da5f43b87ec45bc9c04550njn vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode)); 766ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 767ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Don't let the stat call fail silently. Filter out some known 768ec61b6509566cf36ab3968d69226cecf177cb0fesewardj sources of noise before complaining, though. */ 769cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(statres)) { 770ec61b6509566cf36ab3968d69226cecf177cb0fesewardj DebugInfo fake_di; 771ec61b6509566cf36ab3968d69226cecf177cb0fesewardj Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL; 772e025eca1d49cdfe5a8cb58ab495763434280333asewardj if (!quiet && VG_(clo_verbosity) > 1) { 773ec61b6509566cf36ab3968d69226cecf177cb0fesewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 774a5acac39bf3be7546222b1316faee5ee524be0d1sewardj fake_di.fsm.filename = filename; 775ec61b6509566cf36ab3968d69226cecf177cb0fesewardj ML_(symerr)(&fake_di, True, "failed to stat64/stat this file"); 776ec61b6509566cf36ab3968d69226cecf177cb0fesewardj } 7779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 7782ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj } 7792ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 780ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Finally, the point of all this stattery: if it's not a regular file, 781ec61b6509566cf36ab3968d69226cecf177cb0fesewardj don't try to read debug info from it. */ 7829c20ece00e07304f66da5f43b87ec45bc9c04550njn if (! VKI_S_ISREG(statbuf.mode)) 7839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 784ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 785ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* no uses of statbuf below here. */ 78615728ab41ea41bf731dcc74ac68354550ced2189bart 787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now we have to guess if this is a text-like mapping, a data-like 788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj mapping, neither or both. The rules are: 789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj text if: x86-linux r and x 791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and x and not w 792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data if: x86-linux r and w 794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and w and not x 795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Background: On x86-linux, objects are typically mapped twice: 797eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 798eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so 799eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so 800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 801eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas ppc32-linux mysteriously does this: 802eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 803eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so 804eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so 805eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so 806eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 807eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The third mapping should not be considered to have executable 808eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj code in. Therefore a test which works for both is: r and x and 809eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj NOT w. Reading symbols from the rwx segment -- which overlaps 810eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj the r-x segment in the file -- causes the redirection mechanism 811eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj to redirect to addresses in that third segment, which is wrong 812eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and causes crashes. 813eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 814eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to 815eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj produce executables with a single rwx segment rather than a 816eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (r-x,rw-) pair. That means the rules have to be modified thusly: 817eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 818eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj x86-linux: consider if r and x 819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all others: consider if r and x and not w 820f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj 821f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj 2009 Aug 16: apply similar kludge to ppc32-linux. 822f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj See http://bugs.kde.org/show_bug.cgi?id=190820 823b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 824b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj There are two modes on s390x: with and without the noexec kernel 825b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj parameter. Together with some older kernels, this leads to several 826b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj variants: 827b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj executable: r and x 828b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj data: r and w and x 829b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj or 830b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj executable: r and x 831b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj data: r and w 832eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = False; 834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = False; 835731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is_ro_map = False; 836731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 8374df0bfc0614379192c780c944415dc420d9cfe8epetarj# if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) \ 8384df0bfc0614379192c780c944415dc420d9cfe8epetarj || defined(VGA_mips64) 839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX; 840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW; 841cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \ 842cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGA_arm) || defined(VGA_arm64) 843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW && !seg->hasX; 845b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGP_s390x_linux) 846b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 847b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is_rw_map = seg->hasR && seg->hasW; 848eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# else 849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# error "Unknown platform" 850eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 851eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 852588cd4ebce3305d0cf91896c1f6322ef9775d6c1sewardj# if defined(VGP_x86_darwin) && DARWIN_VERS >= DARWIN_10_7 853731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is_ro_map = seg->hasR && !seg->hasW && !seg->hasX; 854731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 855731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 8576f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-3: " 8586f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "is_rx_map %d, is_rw_map %d, is_ro_map %d\n", 8596f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj (Int)is_rx_map, (Int)is_rw_map, (Int)is_ro_map); 860eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 861731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ignore mappings with permissions we can't possibly be interested in. */ 862731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!(is_rx_map || is_rw_map || is_ro_map)) 8639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 864eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8655a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* Peer at the first few bytes of the file, to see if it is an ELF */ 8665a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* object file. Ignore the file if we do not have read permission. */ 8675a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(buf1k, 0, sizeof(buf1k)); 868cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags = VKI_O_RDONLY; 869cec083d9a254e92623ed44e9dca080d224693c82sewardj# if defined(VKI_O_LARGEFILE) 870cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags |= VKI_O_LARGEFILE; 871cec083d9a254e92623ed44e9dca080d224693c82sewardj# endif 8725f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 8735f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 8745f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj SysRes fd = VG_(open)( filename, oflags, 0 ); 8755f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(fd)) { 8765f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Err(fd) != VKI_EACCES) { 8775f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj DebugInfo fake_di; 8785f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 8795f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj fake_di.fsm.filename = filename; 8805f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj ML_(symerr)(&fake_di, True, 8815f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj "can't open file to inspect ELF header"); 8825f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 8835f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 8845a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 8855f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = sr_Res(fd); 8865f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } else { 8875f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = use_fd; 8885a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 8895a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 8905f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 ); 8915f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 8925f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(close)( actual_fd ); 8935f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 8945f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 8955f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(preadres)) { 8965a5eec0923d55afc94165721d25125d5fc8f24d8sewardj DebugInfo fake_di; 8975a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 898a5acac39bf3be7546222b1316faee5ee524be0d1sewardj fake_di.fsm.filename = filename; 8995a5eec0923d55afc94165721d25125d5fc8f24d8sewardj ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); 9005a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 9015a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 9025f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Res(preadres) == 0) 9035f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 9045f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) ); 9055a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 9068b68b64759254d514d98328c496cbd88cde4c9a5njn /* We're only interested in mappings of object files. */ 9076e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# if defined(VGO_linux) 908f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False )) 9095a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 9106e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# elif defined(VGO_darwin) 9115f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) )) 912f76d27a697a7b0bf3b84490baf60623fc96a23afnjn return 0; 9136e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# else 9146e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# error "unknown OS" 9156e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# endif 9165a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if we have a DebugInfo for this filename. If not, 918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. */ 9190f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj di = find_or_create_DebugInfo_for( filename ); 920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 9226f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 9236f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-4: " 9246f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "noting details in DebugInfo* at %p\n", di); 9256f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 9266b5625bb609b154766d2e138b61e15655f60b710sewardj /* Note the details about the mapping. */ 9276b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping map; 9286b5625bb609b154766d2e138b61e15655f60b710sewardj map.avma = a; 9296b5625bb609b154766d2e138b61e15655f60b710sewardj map.size = seg->end + 1 - seg->start; 9306b5625bb609b154766d2e138b61e15655f60b710sewardj map.foff = seg->offset; 9316b5625bb609b154766d2e138b61e15655f60b710sewardj map.rx = is_rx_map; 9326b5625bb609b154766d2e138b61e15655f60b710sewardj map.rw = is_rw_map; 9336b5625bb609b154766d2e138b61e15655f60b710sewardj map.ro = is_ro_map; 9346b5625bb609b154766d2e138b61e15655f60b710sewardj VG_(addToXA)(di->fsm.maps, &map); 9356b5625bb609b154766d2e138b61e15655f60b710sewardj 9366b5625bb609b154766d2e138b61e15655f60b710sewardj /* Update flags about what kind of mappings we've already seen. */ 9376b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rx_map |= is_rx_map; 9386b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rw_map |= is_rw_map; 9396b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map |= is_ro_map; 940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 941731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* So, finally, are we in an accept state? */ 942731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 943731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ok, so, finally, we found what we need, and we haven't 944731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj already read debuginfo for this object. So let's do so now. 945731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Yee-ha! */ 9466f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 9476f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-5: " 9486f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "achieved accept state for %s\n", filename); 949731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return di_notify_ACHIEVE_ACCEPT_STATE ( di ); 9509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } else { 951731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* If we don't have an rx and rw mapping, or if we already have 952731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj debuginfo for this mapping for whatever reason, go no 953731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj further. */ 954731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return 0; 9559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 956eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 957eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 958eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 959eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Unmap is simpler - throw away any SegInfos intersecting 960eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj [a, a+len). */ 961eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_munmap)( Addr a, SizeT len ) 962eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 963f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound; 964a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len); 965f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = discard_syms_in_range(a, len); 966f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 9675c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 968eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 969eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 970eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 971eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't 972eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj remember) does a bunch of mprotects on itself, and if we follow 973eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj through here, it causes the debug info for that object to get 974eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discarded. */ 975eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 976eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 977eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool exe_ok = toBool(prot & VKI_PROT_EXEC); 978f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# if defined(VGA_x86) 979eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj exe_ok = exe_ok || toBool(prot & VKI_PROT_READ); 980eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 981f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && !exe_ok) { 982f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = discard_syms_in_range(a, len); 983f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 9845c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 985f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 986eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 987eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 988731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 989588cd4ebce3305d0cf91896c1f6322ef9775d6c1sewardj/* This is a MacOSX >= 10.7 32-bit only special. See comments on the 990731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj declaration of struct _DebugInfoFSM for details. */ 991731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardjvoid VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot ) 992731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj{ 9936f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool debug = (DEBUG_FSM != 0); 9946f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 9956f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool r_ok = toBool(prot & VKI_PROT_READ); 9966f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool w_ok = toBool(prot & VKI_PROT_WRITE); 9976f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool x_ok = toBool(prot & VKI_PROT_EXEC); 9986f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) { 9996f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-0:\n"); 10006f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-1: %#lx-%#lx %c%c%c\n", 10016f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj a, a + len - 1, 10026f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj r_ok ? 'r' : '-', w_ok ? 'w' : '-', x_ok ? 'x' : '-' ); 10036f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 10046f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 1005731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool do_nothing = True; 1006ec66ad5f33a4d904b1f728935ec6ee29b58a55ecsewardj# if defined(VGP_x86_darwin) && (DARWIN_VERS >= DARWIN_10_7) 1007731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj do_nothing = False; 1008731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 10096f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (do_nothing /* wrong platform */) { 10106f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10116f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-2: wrong platform, " 10126f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "doing nothing.\n"); 1013731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; 10146f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 1015731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1016731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (! (r_ok && !w_ok && x_ok)) 1017731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* not an upgrade to r-x */ 1018731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1019731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Find a DebugInfo containing a FSM that has [a, +len) previously 1020731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj observed as a r-- mapping, plus some other rw- mapping. If such 1021731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is found, conclude we're in an accept state and read debuginfo 1022731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj accordingly. */ 10236f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10246f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-3: looking for existing DebugInfo*\n"); 1025731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj DebugInfo* di; 10266b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping *map = NULL; 10276b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 1028731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj for (di = debugInfo_list; di; di = di->next) { 1029731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.filename); 1030731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->have_dinfo) 1031731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* already have debuginfo for this object */ 1032731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_ro_map) 1033731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a r-- mapping for this object */ 1034731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map) 1035731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* rx- mapping already exists */ 1036731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_rw_map) 1037731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a rw- mapping */ 10386b5625bb609b154766d2e138b61e15655f60b710sewardj /* Try to find a mapping matching the memory area. */ 10396b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 10406b5625bb609b154766d2e138b61e15655f60b710sewardj map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i); 10416b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro && map->avma == a && map->size == len) 10426b5625bb609b154766d2e138b61e15655f60b710sewardj break; 10436b5625bb609b154766d2e138b61e15655f60b710sewardj map = NULL; 10446b5625bb609b154766d2e138b61e15655f60b710sewardj } 10456b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map) 10466b5625bb609b154766d2e138b61e15655f60b710sewardj continue; /* this isn't an upgrade of an r-- mapping */ 1047731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* looks like we're in luck! */ 1048731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj break; 1049731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } 1050731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di == NULL) 1051731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* didn't find anything */ 1052731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 10536f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10546f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-4: found existing DebugInfo* at %p\n", 10556f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj di); 10566f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 10576b5625bb609b154766d2e138b61e15655f60b710sewardj /* Do the upgrade. Simply update the flags of the mapping 10586b5625bb609b154766d2e138b61e15655f60b710sewardj and pretend we never saw the RO map at all. */ 1059731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.have_ro_map); 10606b5625bb609b154766d2e138b61e15655f60b710sewardj map->rx = True; 10616b5625bb609b154766d2e138b61e15655f60b710sewardj map->ro = False; 1062731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_rx_map = True; 1063731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_ro_map = False; 10646b5625bb609b154766d2e138b61e15655f60b710sewardj /* See if there are any more ro mappings */ 10656b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 10666b5625bb609b154766d2e138b61e15655f60b710sewardj map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i); 10676b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro) { 10686b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map = True; 10696b5625bb609b154766d2e138b61e15655f60b710sewardj break; 10706b5625bb609b154766d2e138b61e15655f60b710sewardj } 10716b5625bb609b154766d2e138b61e15655f60b710sewardj } 10726b5625bb609b154766d2e138b61e15655f60b710sewardj 10736b5625bb609b154766d2e138b61e15655f60b710sewardj /* Check if we're now in an accept state and read debuginfo. Finally. */ 10746b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 10756f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10766f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-5: " 10776f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "achieved accept state for %s\n", di->fsm.filename); 10786b5625bb609b154766d2e138b61e15655f60b710sewardj ULong di_handle __attribute__((unused)) 10796b5625bb609b154766d2e138b61e15655f60b710sewardj = di_notify_ACHIEVE_ACCEPT_STATE( di ); 10806b5625bb609b154766d2e138b61e15655f60b710sewardj /* di_handle is ignored. That's not a problem per se -- it just 10816b5625bb609b154766d2e138b61e15655f60b710sewardj means nobody will ever be able to refer to this debuginfo by 10826b5625bb609b154766d2e138b61e15655f60b710sewardj handle since nobody will know what the handle value is. */ 10836b5625bb609b154766d2e138b61e15655f60b710sewardj } 1084731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj} 1085731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1086731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1087c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------- PDB (windows debug info) reading --------- */ 1088c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1089c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* this should really return ULong, as per VG_(di_notify_mmap). */ 1090c8259b85b701d25d72aabe9dc0a8154517f96913sewardjvoid VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, 109154c45db2f978055aeca91aaccb05aac825523e6csewardj SizeT total_size, PtrdiffT bias_obj ) 1092c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 109313ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int i, r, sz_exename; 1094c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ULong obj_mtime, pdb_mtime; 109554fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian HChar exename[VKI_PATH_MAX]; 10961636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* pdbname = NULL; 10971636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* dot; 1098c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SysRes sres; 1099c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Int fd_pdbimage; 1100c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SizeT n_pdbimage; 1101c8259b85b701d25d72aabe9dc0a8154517f96913sewardj struct vg_stat stat_buf; 1102c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1103c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1104738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "\n"); 1105c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, 1106cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, " 110754c45db2f978055aeca91aaccb05aac825523e6csewardj "bias=%#lx\n", 110854c45db2f978055aeca91aaccb05aac825523e6csewardj fd_obj, avma_obj, total_size, bias_obj 1109c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ); 1110c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1111c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1112c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification 1113c8259b85b701d25d72aabe9dc0a8154517f96913sewardj time into obj_mtime. */ 1114c8259b85b701d25d72aabe9dc0a8154517f96913sewardj r = VG_(fstat)(fd_obj, &stat_buf); 1115c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (r == -1) 1116c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* stat failed ?! */ 1117c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(r == 0); 11189c20ece00e07304f66da5f43b87ec45bc9c04550njn obj_mtime = stat_buf.mtime; 1119c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1120c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* and get its name into exename[]. */ 1121c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(VKI_PATH_MAX > 100); /* to ensure /proc/self/fd/%d is safe */ 1122c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(memset)(exename, 0, sizeof(exename)); 1123c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(sprintf)(exename, "/proc/self/fd/%d", fd_obj); 1124c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* convert exename from a symlink to real name .. overwrites the 1125c8259b85b701d25d72aabe9dc0a8154517f96913sewardj old contents of the buffer. Ick. */ 1126c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sz_exename = VG_(readlink)(exename, exename, sizeof(exename)-2 ); 1127c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (sz_exename == -1) 1128c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* readlink failed ?! */ 1129c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(sz_exename >= 0 && sz_exename < sizeof(exename)); 1130c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(exename[sizeof(exename)-1] == 0); 1131c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1132c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1133738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename); 1134c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1135c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 113613ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to get the PDB file name from the executable. */ 113713ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(find_name_of_pdb_file)(exename); 113813ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname) { 113913ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */ 114013ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* So we successfully extracted a name from the PE file. But it's 114113ac96dea734b3933a73524b991ac64fb48a4d57sewardj likely to be of the form 114213ac96dea734b3933a73524b991ac64fb48a4d57sewardj e:\foo\bar\xyzzy\wibble.pdb 114313ac96dea734b3933a73524b991ac64fb48a4d57sewardj and we need to change it into something we can actually open 114413ac96dea734b3933a73524b991ac64fb48a4d57sewardj in Wine-world, which basically means turning it into 114513ac96dea734b3933a73524b991ac64fb48a4d57sewardj $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 114613ac96dea734b3933a73524b991ac64fb48a4d57sewardj We also take into account $WINEPREFIX, if it is set. 114713ac96dea734b3933a73524b991ac64fb48a4d57sewardj For the moment, if the name isn't fully qualified, just forget it 114813ac96dea734b3933a73524b991ac64fb48a4d57sewardj (we'd have to root around to find where the pdb actually is) 114913ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 115013ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change all the backslashes to forward slashes */ 115113ac96dea734b3933a73524b991ac64fb48a4d57sewardj for (i = 0; pdbname[i]; i++) { 115213ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname[i] == '\\') 115313ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname[i] = '/'; 115413ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 115513ac96dea734b3933a73524b991ac64fb48a4d57sewardj Bool is_quald 115613ac96dea734b3933a73524b991ac64fb48a4d57sewardj = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z') 115713ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[1] == ':' 115813ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[2] == '/'; 115913ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* home = VG_(getenv)("HOME"); 116013ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* wpfx = VG_(getenv)("WINEPREFIX"); 116113ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (is_quald && wpfx) { 116213ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 116313ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb 116413ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 116513ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/; 116613ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB); 116798500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s", 116898500e2ee5f63f9c0af57835f7620d30848115f4bart wpfx, pdbname[0], &pdbname[2]); 116913ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 117013ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 117113ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 117213ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 117313ac96dea734b3933a73524b991ac64fb48a4d57sewardj else if (is_quald && home && !wpfx) { 117413ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 117513ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 117613ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 117713ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/; 117813ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB); 117998500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s", 118098500e2ee5f63f9c0af57835f7620d30848115f4bart home, pdbname[0], &pdbname[2]); 118113ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 118213ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 118313ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 118413ac96dea734b3933a73524b991ac64fb48a4d57sewardj } else { 118513ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* It's not a fully qualified path, or neither $HOME nor $WINE 118613ac96dea734b3933a73524b991ac64fb48a4d57sewardj are set (strange). Give up. */ 118713ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 118813ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = NULL; 118913ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 119013ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1191c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 119213ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try s/exe/pdb/ if we don't have a valid pdbname. */ 119313ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!pdbname) { 119413ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to find a matching PDB file from which to read debuginfo. 119513ac96dea734b3933a73524b991ac64fb48a4d57sewardj Windows PE files have symbol tables and line number information, 119613ac96dea734b3933a73524b991ac64fb48a4d57sewardj but MSVC doesn't seem to use them. */ 119713ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Why +5 ? Because in the worst case, we could find a dot as the 119813ac96dea734b3933a73524b991ac64fb48a4d57sewardj last character of pdbname, and we'd then put "pdb" right after 119913ac96dea734b3933a73524b991ac64fb48a4d57sewardj it, hence extending it a bit. */ 120013ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5); 120113ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(pdbname, exename); 120213ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 120313ac96dea734b3933a73524b991ac64fb48a4d57sewardj dot = VG_(strrchr)(pdbname, '.'); 120413ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!dot) 120513ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* there's no dot in the exe's name ?! */ 120613ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (dot[1] == 0) 120713ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* hmm, path ends in "." */ 120813ac96dea734b3933a73524b991ac64fb48a4d57sewardj 120913ac96dea734b3933a73524b991ac64fb48a4d57sewardj if ('A' <= dot[1] && dot[1] <= 'Z') 121013ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".PDB"); 121113ac96dea734b3933a73524b991ac64fb48a4d57sewardj else 121213ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".pdb"); 121313ac96dea734b3933a73524b991ac64fb48a4d57sewardj 121413ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 121513ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1216c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1217c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* See if we can find it, and check it's in-dateness. */ 1218c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(stat)(pdbname, &stat_buf); 1219cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1220738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n", 1221c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname); 1222c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1223738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname); 1224c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1225c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 12269c20ece00e07304f66da5f43b87ec45bc9c04550njn pdb_mtime = stat_buf.mtime; 12277138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj 1228ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj if (obj_mtime > pdb_mtime + 60ULL) { 12297138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj /* PDB file is older than PE file. Really, the PDB should be 12307138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj newer than the PE, but that doesn't always seem to be the 12317138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj case. Allow the PDB to be up to one minute older. 12327138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj Otherwise, it's probably out of date, in which case ignore it 12337138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj or we will either (a) print wrong stack traces or more likely 12347138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj (b) crash. 12357138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj */ 1236738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, 1237ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj "Warning: %s (mtime = %llu)\n" 1238ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj " is older than %s (mtime = %llu)\n", 1239ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj pdbname, pdb_mtime, exename, obj_mtime); 1240c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1241c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1242c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(open)(pdbname, VKI_O_RDONLY, 0); 1243cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1244738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname); 1245c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1246c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1247c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1248cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj /* Looks promising; go on to try and read stuff from it. But don't 1249cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj mmap the file. Instead mmap free space and read the file into 1250cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj it. This is because files on CIFS filesystems that are mounted 1251cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj '-o directio' can't be mmap'd, and that mount option is needed 1252cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj to make CIFS work reliably. (See 1253cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj http://www.nabble.com/Corrupted-data-on-write-to- 1254cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj Windows-2003-Server-t2782623.html) 1255cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj This is slower, but at least it works reliably. */ 1256cda2f0fbda4c4b2644babc830244be8aed95de1dnjn fd_pdbimage = sr_Res(sres); 12579c20ece00e07304f66da5f43b87ec45bc9c04550njn n_pdbimage = stat_buf.size; 1258cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) { 1259cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // 0x7FFFFFFF: why? Because the VG_(read) just below only 1260cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // can deal with a signed int as the size of data to read, 1261cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // so we can't reliably check for read failure for files 1262cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // greater than that size. Hence just skip them; we're 1263cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // unlikely to encounter a PDB that large anyway. 1264cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1265cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1266cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1267cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage ); 1268cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1269c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1270c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1271c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1272c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1273cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj void* pdbimage = (void*)sr_Res(sres); 1274cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage ); 1275cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (r < 0 || r != (Int)n_pdbimage) { 1276cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1277cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1278cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1279cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1280cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1281c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1282738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname); 1283c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1284c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* play safe; always invalidate the CFI cache. I don't know if 1285c8259b85b701d25d72aabe9dc0a8154517f96913sewardj this is necessary, but anyway .. */ 12865c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 1287c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* dump old info for this range, if any */ 1288c8259b85b701d25d72aabe9dc0a8154517f96913sewardj discard_syms_in_range( avma_obj, total_size ); 1289c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 12900f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj { DebugInfo* di = find_or_create_DebugInfo_for(exename); 1291c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1292c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* this di must be new, since we just nuked any old stuff in the range */ 1293a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map); 1294c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(!di->have_dinfo); 1295c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1296c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* don't set up any of the di-> fields; let 1297c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ML_(read_pdb_debug_info) do it. */ 129854c45db2f978055aeca91aaccb05aac825523e6csewardj ML_(read_pdb_debug_info)( di, avma_obj, bias_obj, 1299c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbimage, n_pdbimage, pdbname, pdb_mtime ); 1300c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // JRS fixme: take notice of return value from read_pdb_debug_info, 1301c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // and handle failure 1302c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(di->have_dinfo); // fails if PDB read failed 1303c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1304c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1305cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1306cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (VG_(clo_verbosity) > 0) { 1307cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done: " 1308a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "%lu syms, %lu src locs, " 1309a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "%lu src locs, %lu fpo recs\n", 1310a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->symtab_used, di->loctab_used, 1311a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->inltab_used, di->fpo_size); 1312cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1313c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1314c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1315c8259b85b701d25d72aabe9dc0a8154517f96913sewardj out: 1316c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (pdbname) ML_(dinfo_free)(pdbname); 1317c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 1318c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 13198b68b64759254d514d98328c496cbd88cde4c9a5njn#endif /* defined(VGO_linux) || defined(VGO_darwin) */ 13204ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 13214ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/ 1325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 13289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid VG_(di_discard_ALL_debuginfo)( void ) 13299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 13309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo *di, *di2; 13319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = debugInfo_list; 13329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while (di) { 13339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di2 = di->next; 13349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("XXX rm %p\n", di); 13359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj free_DebugInfo( di ); 13369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = di2; 13379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 13389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 13399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 13409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 13416b5625bb609b154766d2e138b61e15655f60b710sewardjstruct _DebugInfoMapping* ML_(find_rx_mapping) ( struct _DebugInfo* di, 13426b5625bb609b154766d2e138b61e15655f60b710sewardj Addr lo, Addr hi ) 13436b5625bb609b154766d2e138b61e15655f60b710sewardj{ 13446b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 13456b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(lo <= hi); 13466b5625bb609b154766d2e138b61e15655f60b710sewardj 13476b5625bb609b154766d2e138b61e15655f60b710sewardj /* Optimization: Try to use the last matched rx mapping first */ 13486b5625bb609b154766d2e138b61e15655f60b710sewardj if ( di->last_rx_map 13496b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= di->last_rx_map->avma 13506b5625bb609b154766d2e138b61e15655f60b710sewardj && hi < di->last_rx_map->avma + di->last_rx_map->size) 13516b5625bb609b154766d2e138b61e15655f60b710sewardj return di->last_rx_map; 13526b5625bb609b154766d2e138b61e15655f60b710sewardj 13536b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 13546b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 13556b5625bb609b154766d2e138b61e15655f60b710sewardj if ( map->rx && map->size > 0 13566b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= map->avma && hi < map->avma + map->size) { 13576b5625bb609b154766d2e138b61e15655f60b710sewardj di->last_rx_map = map; 13586b5625bb609b154766d2e138b61e15655f60b710sewardj return map; 13596b5625bb609b154766d2e138b61e15655f60b710sewardj } 13606b5625bb609b154766d2e138b61e15655f60b710sewardj } 13616b5625bb609b154766d2e138b61e15655f60b710sewardj 13626b5625bb609b154766d2e138b61e15655f60b710sewardj return NULL; 13636b5625bb609b154766d2e138b61e15655f60b710sewardj} 13646b5625bb609b154766d2e138b61e15655f60b710sewardj 1365a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*------------------------------------------------------------*/ 1366a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*--- Types and functions for inlined IP cursor ---*/ 1367a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*------------------------------------------------------------*/ 1368a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestruct _InlIPCursor { 1369a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Addr eip; // Cursor used to describe calls at eip. 1370a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo* di; // DebugInfo describing inlined calls at eip 1371a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1372a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word inltab_lopos; // The inlined fn calls covering eip are in 1373a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word inltab_hipos; // di->inltab[inltab_lopos..inltab_hipos]. 1374a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // Note that not all inlined fn calls in this range 1375a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // are necessarily covering eip. 1376a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1377a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Int curlevel; // Current level to describe. 1378a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // 0 means to describe eip itself. 1379a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word cur_inltab; // inltab pos for call inlined at current level. 1380a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word next_inltab; // inltab pos for call inlined at next (towards main) 1381a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // level. 1382a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}; 1383a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1384a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Bool is_top(InlIPCursor *iipc) 1385a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1386a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return !iipc || iipc->cur_inltab == -1; 1387a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1388a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1389a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Bool is_bottom(InlIPCursor *iipc) 1390a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1391a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return !iipc || iipc->next_inltab == -1; 1392a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1393a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1394a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeBool VG_(next_IIPC)(InlIPCursor *iipc) 1395a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1396a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word i; 1397a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DiInlLoc *hinl = NULL; 1398a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word hinl_pos = -1; 1399a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo *di; 1400a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1401a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc == NULL) 1402a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return False; 1403a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1404a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc->curlevel <= 0) { 1405a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel--; 1406a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return False; 1407a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1408a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1409a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di = iipc->di; 1410a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = iipc->inltab_lopos; i <= iipc->inltab_hipos; i++) { 1411a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo <= iipc->eip 1412a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && iipc->eip < di->inltab[i].addr_hi 1413a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && di->inltab[i].level < iipc->curlevel 1414a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && (!hinl || hinl->level < di->inltab[i].level)) { 1415a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hinl = &di->inltab[i]; 1416a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hinl_pos = i; 1417a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1418a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1419a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1420a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->cur_inltab = iipc->next_inltab; 1421a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->next_inltab = hinl_pos; 1422a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc->next_inltab < 0) 1423a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel = 0; // no inlined call anymore, describe eip itself 1424a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe else 1425a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel = di->inltab[iipc->next_inltab].level; 1426a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1427a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return True; 1428a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1429a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1430a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Forward */ 1431a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1432a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*OUT*/Word* locno ); 1433a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1434a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Returns the position after which eip would be inserted in inltab. 1435a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (-1 if eip should be inserted before position 0). 1436a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe This is the highest position with an addr_lo <= eip. 1437a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe As inltab is sorted on addr_lo, dichotomic search can be done 1438a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (note that inltab might have duplicates addr_lo). */ 1439a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Word inltab_insert_pos (DebugInfo *di, Addr eip) 1440a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1441a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word mid, 1442a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo = 0, 1443a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hi = di->inltab_used-1; 1444a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe while (lo <= hi) { 1445a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe mid = (lo + hi) / 2; 1446a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip < di->inltab[mid].addr_lo) { hi = mid-1; continue; } 1447a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip > di->inltab[mid].addr_lo) { lo = mid+1; continue; } 1448a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo = mid; break; 1449a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1450a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1451a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe while (lo <= di->inltab_used-1 && di->inltab[lo].addr_lo <= eip) 1452a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo++; 1453a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe#if 0 1454a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (mid = 0; mid <= di->inltab_used-1; mid++) 1455a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip < di->inltab[mid].addr_lo) 1456a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; 1457a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (lo - 1 == mid - 1); 1458a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe#endif 1459a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return lo - 1; 1460a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1461a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1462a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeInlIPCursor* VG_(new_IIPC)(Addr eip) 1463a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1464a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo* di; 1465a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word locno; 1466a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word i; 1467a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe InlIPCursor *ret; 1468a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool avail; 1469a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1470a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (!VG_(clo_read_inline_info)) 1471a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No way we can find inlined calls. 1472a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1473a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Search the DebugInfo for eip */ 1474a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe search_all_loctabs ( eip, &di, &locno ); 1475a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di == NULL || di->inltab_used == 0) 1476a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No di (with inltab) containing eip. 1477a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1478a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Search the entry in di->inltab with the highest addr_lo that 1479a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe contains eip. */ 1480a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* We start from the highest pos in inltab after which eip would 1481a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe be inserted. */ 1482a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = inltab_insert_pos (di, eip); i >= 0; i--) { 1483a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo <= eip && eip < di->inltab[i].addr_hi) { 1484a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; 1485a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1486a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Stop the backward scan when reaching an addr_lo which 1487a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe cannot anymore contain eip : we know that all ranges before 1488a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe i also cannot contain eip. */ 1489a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) 1490a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; 1491a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1492a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1493a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (i < 0) 1494a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No entry containing eip. 1495a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1496a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* We have found the highest entry containing eip. 1497a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Build a cursor. */ 1498a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret = ML_(dinfo_zalloc) ("dinfo.new_IIPC", sizeof(*ret)); 1499a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->eip = eip; 1500a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->di = di; 1501a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->inltab_hipos = i; 1502a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = ret->inltab_hipos - 1; i >= 0; i--) { 1503a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1504a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) 1505a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; /* Similar stop backward scan logic as above. */ 1506a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1507a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->inltab_lopos = i + 1; 1508a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->curlevel = MAX_LEVEL; 1509a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->cur_inltab = -1; 1510a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->next_inltab = -1; 1511a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1512a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* MAX_LEVEL is higher than any stored level. We can use 1513a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(next_IIPC) to get to the 'real' first highest call level. */ 1514a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe avail = VG_(next_IIPC) (ret); 1515a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (avail); 1516a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1517a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return ret; 1518a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1519a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1520a0a73939b0398b6608fd6dbde49820ce6530d12cphilippevoid VG_(delete_IIPC)(InlIPCursor *iipc) 1521a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1522a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc) 1523a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ML_(dinfo_free)( iipc ); 1524a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1525a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 15266b5625bb609b154766d2e138b61e15655f60b710sewardj 1527eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1528eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Use of symbol table & location info to create ---*/ 1529eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- plausible-looking stack dumps. ---*/ 1530eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1531eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1532eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all symtabs that we know about to locate ptr. If found, set 1533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *symno to the symtab entry 1534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *psi is set to NULL. 1535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==True, only text symbols are searched for. 1536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==False, only data symbols are searched for. 1537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 1538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1539f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* symno, 1540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, 1541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText ) 1542eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1543f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool inRange; 1546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (findText) { 155051c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj /* Consider any symbol in the r-x mapped area to be text. 155151c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj See Comment_Regarding_Text_Range_Checks in storage.c for 155251c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj details. */ 1553a5acac39bf3be7546222b1316faee5ee524be0d1sewardj inRange = di->fsm.have_rx_map 15546b5625bb609b154766d2e138b61e15655f60b710sewardj && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL); 1555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = (di->data_present 1557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 1558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_avma <= ptr 1559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->data_avma + di->data_size) 1560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->sdata_present 1562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 1563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_avma <= ptr 1564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->sdata_avma + di->sdata_size) 1565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->bss_present 1567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 1568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_avma <= ptr 15695706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->bss_avma + di->bss_size) 15705706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 15715706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->sbss_present 15725706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 15735706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_avma <= ptr 15745706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->sbss_avma + di->sbss_size) 15755706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 15765706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->rodata_present 15775706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_size > 0 15785706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_avma <= ptr 15795706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->rodata_avma + di->rodata_size); 1580eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!inRange) continue; 1583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sno = ML_(search_one_symtab) ( 1585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di, ptr, match_anywhere_in_sym, findText ); 1586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (sno == -1) goto not_found; 1587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *symno = sno; 1588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1591eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1592eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1594eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1595eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1596eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1597eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all loctabs that we know about to locate ptr. If found, set 1598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *locno to the loctab entry 1599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *pdi is set to NULL. */ 1600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1601f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* locno ) 1602eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1603f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word lno; 1604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 16075706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size) { 1610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj lno = ML_(search_one_loctab) ( di, ptr ); 1611eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lno == -1) goto not_found; 1612eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *locno = lno; 1613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1614eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1615eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1616eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1617eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1619eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1620eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1621eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1622eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The whole point of this whole big deal: map a code address to a 1623eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj plausible symbol name. Returns False if no idea; otherwise True. 16246b7611bf42a0fbb62e047d8c43b008205bd21e75njn Caller supplies buf and nbuf. If do_cxx_demangling is False, don't do 16256b7611bf42a0fbb62e047d8c43b008205bd21e75njn C++ demangling, regardless of VG_(clo_demangle) -- probably because the 16266b7611bf42a0fbb62e047d8c43b008205bd21e75njn call has come from VG_(get_fnname_raw)(). findText 1627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj indicates whether we're looking for a text symbol or a data symbol 1628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj -- caller must choose one kind or the other. */ 1629eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 16306b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, 16316b7611bf42a0fbb62e047d8c43b008205bd21e75njn Bool do_below_main_renaming, 16321636d33c13958b9c0e7d3059cdd5005746418eb2florian Addr a, HChar* buf, Int nbuf, 1633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, Bool show_offset, 1634c4431bfe04c7490ea2d74939d222d87f13f30960njn Bool findText, /*OUT*/PtrdiffT* offsetP ) 1635eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1637f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1638c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 1639eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); 1641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 1642eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 16436882443ef154bca367bc591287de641e43a9e108njn 1644a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(di->symtab[sno].pri_name); 16456b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(demangle) ( do_cxx_demangling, do_z_demangling, 1646a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[sno].pri_name, buf, nbuf ); 16476b7611bf42a0fbb62e047d8c43b008205bd21e75njn 16486b7611bf42a0fbb62e047d8c43b008205bd21e75njn /* Do the below-main hack */ 16496b7611bf42a0fbb62e047d8c43b008205bd21e75njn // To reduce the endless nuisance of multiple different names 16506b7611bf42a0fbb62e047d8c43b008205bd21e75njn // for "the frame below main()" screwing up the testsuite, change all 16516b7611bf42a0fbb62e047d8c43b008205bd21e75njn // known incarnations of said into a single name, "(below main)", if 16526b7611bf42a0fbb62e047d8c43b008205bd21e75njn // --show-below-main=yes. 16536b7611bf42a0fbb62e047d8c43b008205bd21e75njn if ( do_below_main_renaming && ! VG_(clo_show_below_main) && 16546b7611bf42a0fbb62e047d8c43b008205bd21e75njn Vg_FnNameBelowMain == VG_(get_fnname_kind)(buf) ) 16556b7611bf42a0fbb62e047d8c43b008205bd21e75njn { 16566b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(strncpy_safely)(buf, "(below main)", nbuf); 1657eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 16584cace66777ca9ee73ea156210c04e9d4cc178395philippe offset = a - di->symtab[sno].avmas.main; 1659c4431bfe04c7490ea2d74939d222d87f13f30960njn if (offsetP) *offsetP = offset; 1660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1661eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (show_offset && offset != 0) { 16621636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar buf2[12]; 16631636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* symend = buf + VG_(strlen)(buf); 16641636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* end = buf + nbuf; 1665eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int len; 1666eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1667c4431bfe04c7490ea2d74939d222d87f13f30960njn len = VG_(sprintf)(buf2, "%c%ld", 1668eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? '-' : '+', 1669eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? -offset : offset); 1670eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(len < (Int)sizeof(buf2)); 1671eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1672eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (len < (end - symend)) { 16731636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar *cp = buf2; 1674eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(memcpy)(symend, cp, len+1); 1675eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1676eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1677eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 16786b7611bf42a0fbb62e047d8c43b008205bd21e75njn buf[nbuf-1] = 0; /* paranoia */ 16796b7611bf42a0fbb62e047d8c43b008205bd21e75njn 1680eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1681eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1682eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1683cae0cc22b83ffb260ee8379e92099c5a701944cbcarll/* ppc64be-linux only: find the TOC pointer (R2 value) that should be in 1684eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj force at the entry point address of the function containing 1685eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj guest_code_addr. Returns 0 if not known. */ 1686eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjAddr VG_(get_tocptr) ( Addr guest_code_addr ) 1687eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 16884cace66777ca9ee73ea156210c04e9d4cc178395philippe#if defined(VGA_ppc64be) || defined(VGA_ppc64le) 1689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1690f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1691eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_symtabs ( guest_code_addr, 1692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj &si, &sno, 1693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*match_anywhere_in_fun*/, 1694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*consider text symbols only*/ ); 1695eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1696eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj else 16984cace66777ca9ee73ea156210c04e9d4cc178395philippe return GET_TOCPTR_AVMA(si->symtab[sno].avmas); 16994cace66777ca9ee73ea156210c04e9d4cc178395philippe#else 17004cace66777ca9ee73ea156210c04e9d4cc178395philippe return 0; 17014cace66777ca9ee73ea156210c04e9d4cc178395philippe#endif 1702eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1703eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1704eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1705eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, but don't show offsets. */ 17061636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_fnname) ( Addr a, HChar* buf, Int nbuf ) 1707eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 17086b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 17096b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 17106b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1715eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1716eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1717eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1718eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, and show offset if nonzero. */ 17191636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_fnname_w_offset) ( Addr a, HChar* buf, Int nbuf ) 1720eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 17216b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 17226b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 17236b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/True, 1726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1728eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1729eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1730eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1731eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj only succeed if 'a' matches first instruction of function, 1732eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and don't show offsets. */ 17331636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_fnname_if_entry) ( Addr a, HChar* buf, Int nbuf ) 1734eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 17356b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 17366b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 17376b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/False, 1739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1742eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1743eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 17446b7611bf42a0fbb62e047d8c43b008205bd21e75njn/* This is only available to core... don't C++-demangle, don't Z-demangle, 17456b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't rename below-main, match anywhere in function, and don't show 17466b7611bf42a0fbb62e047d8c43b008205bd21e75njn offsets. */ 17471636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_fnname_raw) ( Addr a, HChar* buf, Int nbuf ) 1748eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 17496b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 17506b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 17516b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1756eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1757eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1758eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, but do 17596b7611bf42a0fbb62e047d8c43b008205bd21e75njn do Z-demangling and below-main-renaming, match anywhere in function, and 17606b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't show offsets. */ 1761a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeBool VG_(get_fnname_no_cxx_demangle) ( Addr a, HChar* buf, Int nbuf, 1762a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe InlIPCursor* iipc ) 1763eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1764a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_bottom(iipc)) { 1765a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // At the bottom (towards main), we describe the fn at eip. 1766a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True, 1767a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*below-main-renaming*/True, 1768a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe a, buf, nbuf, 1769a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*match_anywhere_in_fun*/True, 1770a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*show offset?*/False, 1771a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*text syms only*/True, 1772a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*offsetP*/NULL ); 1773a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 1774a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0 1775a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->next_inltab] 1776a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 1777a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (next_inl); 1778a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The function we are in is called by next_inl. 1779a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(snprintf)(buf, nbuf, "%s", next_inl->inlinedfn); 1780a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return True; 1781a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1782eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1783eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 17845db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* mips-linux only: find the offset of current address. This is needed for 17855db15403e889d4db339b342bc2a824ef0bfaa654sewardj stack unwinding for MIPS. 17865db15403e889d4db339b342bc2a824ef0bfaa654sewardj*/ 17875db15403e889d4db339b342bc2a824ef0bfaa654sewardjBool VG_(get_inst_offset_in_function)( Addr a, 17885db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*OUT*/PtrdiffT* offset ) 17895db15403e889d4db339b342bc2a824ef0bfaa654sewardj{ 17901636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar fnname[64]; 17915db15403e889d4db339b342bc2a824ef0bfaa654sewardj return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 17925db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*below-main-renaming*/False, 17935db15403e889d4db339b342bc2a824ef0bfaa654sewardj a, fnname, 64, 17945db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*match_anywhere_in_sym*/True, 179581208182df4e8b9c8642affd6754996777ee7556florian /*show offset?*/False, 17964afac5b6f637d1cea82e62b3a280fa4e81101c05petarj /*text syms only*/True, 17975db15403e889d4db339b342bc2a824ef0bfaa654sewardj offset ); 17985db15403e889d4db339b342bc2a824ef0bfaa654sewardj} 17995db15403e889d4db339b342bc2a824ef0bfaa654sewardj 18001636d33c13958b9c0e7d3059cdd5005746418eb2florianVg_FnNameKind VG_(get_fnname_kind) ( HChar* name ) 18016882443ef154bca367bc591287de641e43a9e108njn{ 18026882443ef154bca367bc591287de641e43a9e108njn if (VG_STREQ("main", name)) { 18036882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameMain; 18046882443ef154bca367bc591287de641e43a9e108njn 18056882443ef154bca367bc591287de641e43a9e108njn } else if ( 18063026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGO_linux) 18076882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("__libc_start_main", name) || // glibc glibness 18086882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness 18093026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGO_darwin) 1810f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // See readmacho.c for an explanation of this. 1811f76d27a697a7b0bf3b84490baf60623fc96a23afnjn VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling 18123026f71684a930286186aa10fef266c304672e8fsewardj# else 18133026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown OS" 18143026f71684a930286186aa10fef266c304672e8fsewardj# endif 18156882443ef154bca367bc591287de641e43a9e108njn 0) { 18166882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameBelowMain; 18176882443ef154bca367bc591287de641e43a9e108njn 18186882443ef154bca367bc591287de641e43a9e108njn } else { 18196882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; 18206882443ef154bca367bc591287de641e43a9e108njn } 18216882443ef154bca367bc591287de641e43a9e108njn} 18226882443ef154bca367bc591287de641e43a9e108njn 18236882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) 18246882443ef154bca367bc591287de641e43a9e108njn{ 18256882443ef154bca367bc591287de641e43a9e108njn // We don't need a big buffer; all the special names are small. 18266882443ef154bca367bc591287de641e43a9e108njn #define BUFLEN 50 18271636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar buf[50]; 18286882443ef154bca367bc591287de641e43a9e108njn 18296882443ef154bca367bc591287de641e43a9e108njn // We don't demangle, because it's faster not to, and the special names 18307d995792542cf8e7f5a81248589445adfffeae30florian // we're looking for won't be mangled. 18316b7611bf42a0fbb62e047d8c43b008205bd21e75njn if (VG_(get_fnname_raw) ( ip, buf, BUFLEN )) { 18326882443ef154bca367bc591287de641e43a9e108njn buf[BUFLEN-1] = '\0'; // paranoia 18336882443ef154bca367bc591287de641e43a9e108njn return VG_(get_fnname_kind)(buf); 18346882443ef154bca367bc591287de641e43a9e108njn } else { 18356882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; // Don't know the name, treat it as normal. 18366882443ef154bca367bc591287de641e43a9e108njn } 18376882443ef154bca367bc591287de641e43a9e108njn} 18386882443ef154bca367bc591287de641e43a9e108njn 1839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Looks up data_addr in the collection of data symbols, and if found 1840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj puts its name (or as much as will fit) into dname[0 .. n_dname-1], 1841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which is guaranteed to be zero terminated. Also data_addr's offset 1842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj from the symbol start is put into *offset. */ 1843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_datasym_and_offset)( Addr data_addr, 18441636d33c13958b9c0e7d3059cdd5005746418eb2florian /*OUT*/HChar* dname, Int n_dname, 1845c4431bfe04c7490ea2d74939d222d87f13f30960njn /*OUT*/PtrdiffT* offset ) 1846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 1848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 18496b7611bf42a0fbb62e047d8c43b008205bd21e75njn ok = get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 18506b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 18516b7611bf42a0fbb62e047d8c43b008205bd21e75njn data_addr, dname, n_dname, 1852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_sym*/True, 1853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*data syms only please*/False, 1855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset ); 1856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!ok) 1857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname[n_dname-1] = 0; 1859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to the name of a shared object file or the 1863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj executable. Returns False if no idea; otherwise True. Doesn't 1864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj require debug info. Caller supplies buf and nbuf. */ 18651636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_objname) ( Addr a, HChar* buf, Int nbuf ) 1866eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1868f32ec7f0de8a651bc16a1b2e448c0106d8669889tom const NSegment *seg; 1869f32ec7f0de8a651bc16a1b2e448c0106d8669889tom HChar* filename; 18704ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj vg_assert(nbuf > 0); 18717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Look in the debugInfo_list to find the name. In most cases we 18727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj expect this to produce a result. */ 1873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 18755706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1878a5acac39bf3be7546222b1316faee5ee524be0d1sewardj VG_(strncpy_safely)(buf, di->fsm.filename, nbuf); 18796625f7115ce012b84712770af22765c01f96ba44florian buf[nbuf-1] = 0; 1880eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1881eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1882eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 18837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Last-ditch fallback position: if we don't find the address in 18847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the debugInfo_list, ask the address space manager whether it 18857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj knows the name of the file associated with this mapping. This 18867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj allows us to print the names of exe/dll files in the stack trace 18877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj when running programs under wine. */ 18887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if ( (seg = VG_(am_find_nsegment(a))) != NULL 18897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj && (filename = VG_(am_get_filename)(seg)) != NULL ) { 1890f32ec7f0de8a651bc16a1b2e448c0106d8669889tom VG_(strncpy_safely)(buf, filename, nbuf); 1891f32ec7f0de8a651bc16a1b2e448c0106d8669889tom return True; 1892f32ec7f0de8a651bc16a1b2e448c0106d8669889tom } 1893eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1894eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1895eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't 1897eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj require debug info. */ 1898e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjDebugInfo* VG_(find_DebugInfo) ( Addr a ) 1899eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1900e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj static UWord n_search = 0; 1901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1902e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj n_search++; 1903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 19055706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1908e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj if (0 == (n_search & 0xF)) 1909e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj move_DebugInfo_one_step_forward( di ); 1910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 1911eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1912eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1913eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return NULL; 1914eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1915eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1916eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename. Returns True if successful. */ 19171636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_filename)( Addr a, HChar* filename, Int n_filename ) 1918eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1920f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 192159e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 192259e1f3c79e870a978d24add86db6d8c5450c8b63philippe 1923eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1924eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1925eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 192659e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix = ML_(fndn_ix) (si, locno); 1927666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe VG_(strncpy_safely)(filename, 1928666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe ML_(fndn_ix2filename) (si, fndn_ix), 1929666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe n_filename); 1930eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1931eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1932eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1933eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a line number. Returns True if successful. */ 1934eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_linenum)( Addr a, UInt* lineno ) 1935eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1937f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1938eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1939eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1940eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1941eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1942eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1943eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1944eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1945eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1946eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename/line number/dir name info. 1947eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj See prototype for detailed description of behaviour. 1948eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 1949eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename_linenum) ( Addr a, 19501636d33c13958b9c0e7d3059cdd5005746418eb2florian /*OUT*/HChar* filename, Int n_filename, 19511636d33c13958b9c0e7d3059cdd5005746418eb2florian /*OUT*/HChar* dirname, Int n_dirname, 1952eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Bool* dirname_available, 1953eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* lineno ) 1954eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1956f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 195759e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 1958eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1959eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert( (dirname == NULL && dirname_available == NULL) 1960eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj || 1961eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (dirname != NULL && dirname_available != NULL) ); 1962eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1963eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1964c1b1d421216369aec58867ce1c5b99cfb1703c36njn if (si == NULL) { 1965db5c6571454c1f647a4c67593805a8e401cd14c5njn if (dirname_available) { 1966db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname_available = False; 1967db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname = 0; 1968db5c6571454c1f647a4c67593805a8e401cd14c5njn } 1969eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1970c1b1d421216369aec58867ce1c5b99cfb1703c36njn } 1971c1b1d421216369aec58867ce1c5b99cfb1703c36njn 197259e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix = ML_(fndn_ix)(si, locno); 1973666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe VG_(strncpy_safely)(filename, 1974666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe ML_(fndn_ix2filename) (si, fndn_ix), 1975666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe n_filename); 1976eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1977eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1978eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (dirname) { 1979eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* caller wants directory info too .. */ 1980eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(n_dirname > 0); 1981666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe VG_(strncpy_safely)(dirname, 1982666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe ML_(fndn_ix2dirname) (si, fndn_ix), 1983666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe n_dirname); 1984666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe *dirname_available = *dirname != 0; 1985eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1986eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1987eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1988eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1989eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1990eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 19914ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* Map a function name to its entry point and toc pointer. Is done by 19924ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj sequential search of all symbol tables, so is very slow. To 19934ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj mitigate the worst performance effects, you may specify a soname 19944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj pattern, and only objects matching that pattern are searched. 19954ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Therefore specify "*" to search all the objects. On TOC-afflicted 19964ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj platforms, a symbol is deemed to be found only if it has a nonzero 19974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj TOC pointer. */ 19984cace66777ca9ee73ea156210c04e9d4cc178395philippeBool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, SymAVMAs* avmas) 19994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 20004ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool require_pToc = False; 20014ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int i; 2002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 20034ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool debug = False; 20044ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VG_PLAT_USES_PPCTOC) 20054ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj require_pToc = True; 20064ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 2007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si; si = si->next) { 20084ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 20094ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname); 20104ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (!VG_(string_match)(sopatt, si->soname)) { 20114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 20124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)(" ... skip\n"); 20134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj continue; 20144ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 20154ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj for (i = 0; i < si->symtab_used; i++) { 20161636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* pri_name = si->symtab[i].pri_name; 2017a5cace0c2a3e212931badbf6398a0cd98393121asewardj tl_assert(pri_name); 2018a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, pri_name) 20194cace66777ca9ee73ea156210c04e9d4cc178395philippe && (require_pToc ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) { 20204cace66777ca9ee73ea156210c04e9d4cc178395philippe *avmas = si->symtab[i].avmas; 20214ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return True; 20224ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 20231636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar** sec_names = si->symtab[i].sec_names; 2024a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sec_names) { 2025a5cace0c2a3e212931badbf6398a0cd98393121asewardj tl_assert(sec_names[0]); 2026a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*sec_names) { 2027a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, *sec_names) 20284cace66777ca9ee73ea156210c04e9d4cc178395philippe && (require_pToc 20294cace66777ca9ee73ea156210c04e9d4cc178395philippe ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) { 20304cace66777ca9ee73ea156210c04e9d4cc178395philippe *avmas = si->symtab[i].avmas; 2031a5cace0c2a3e212931badbf6398a0cd98393121asewardj return True; 2032a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 2033a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec_names++; 2034a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 2035a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 20364ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 20374ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 20384ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return False; 20394ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 20404ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 20414ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 2042e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* VG_(describe_IP): print into buf info on code address, function 2043e872fec0c1c3b478a399fdba42ac65764b53f470sewardj name and filename. */ 2044e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 2045e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Copy str into buf starting at n, but not going past buf[n_buf-1] 2046e872fec0c1c3b478a399fdba42ac65764b53f470sewardj and always ensuring that buf is zero-terminated. */ 2047eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 20481636d33c13958b9c0e7d3059cdd5005746418eb2florianstatic Int putStr ( Int n, Int n_buf, HChar* buf, const HChar* str ) 2049eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2050e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 2051e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 2052eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; n < n_buf-1 && *str != 0; n++,str++) 2053eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = *str; 2054e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 2055eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = '\0'; 2056eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 2057eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2058e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 2059e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Same as putStr, but escaping chars for XML output, and 2060e872fec0c1c3b478a399fdba42ac65764b53f470sewardj also not adding more than count chars to n_buf. */ 2061e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 20621636d33c13958b9c0e7d3059cdd5005746418eb2florianstatic Int putStrEsc ( Int n, Int n_buf, Int count, HChar* buf, HChar* str ) 2063eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 20641636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar alt[2]; 2065e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 2066e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0 && count < n_buf); 2067e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 2068eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; *str != 0; str++) { 2069e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); 2070e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count <= 0) 2071e872fec0c1c3b478a399fdba42ac65764b53f470sewardj goto done; 2072eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (*str) { 2073e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '&': 2074e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 5) goto done; 2075e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "&"); 2076e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 5; 2077e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2078e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '<': 2079e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 2080e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "<"); 2081e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 2082e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2083e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '>': 2084e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 2085e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, ">"); 2086e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 2087e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2088e872fec0c1c3b478a399fdba42ac65764b53f470sewardj default: 2089e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 1) goto done; 2090e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[0] = *str; 2091e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[1] = 0; 2092e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, alt ); 2093e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 1; 2094e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2095eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2096eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2097e872fec0c1c3b478a399fdba42ac65764b53f470sewardj done: 2098e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); /* should not go -ve in loop */ 2099e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 2100eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 2101eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2102eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2103a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeHChar* VG_(describe_IP)(Addr eip, HChar* buf, Int n_buf, InlIPCursor *iipc) 2104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2105eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define APPEND(_str) \ 2106e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr(n, n_buf, buf, _str) 2107e872fec0c1c3b478a399fdba42ac65764b53f470sewardj# define APPEND_ESC(_count,_str) \ 2108e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStrEsc(n, n_buf, (_count), buf, (_str)) 2109eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define BUF_LEN 4096 2110eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2111eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt lineno; 21121636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar ibuf[50]; 2113eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int n = 0; 211414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 2115a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (!iipc || iipc->eip == eip); 2116a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 21171636d33c13958b9c0e7d3059cdd5005746418eb2florian static HChar buf_fn[BUF_LEN]; 21181636d33c13958b9c0e7d3059cdd5005746418eb2florian static HChar buf_obj[BUF_LEN]; 21191636d33c13958b9c0e7d3059cdd5005746418eb2florian static HChar buf_srcloc[BUF_LEN]; 21201636d33c13958b9c0e7d3059cdd5005746418eb2florian static HChar buf_dirname[BUF_LEN]; 212114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_fn[0] = buf_obj[0] = buf_srcloc[0] = buf_dirname[0] = 0; 212214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 2123eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_dirinfo = False; 2124a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_fnname; 2125a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_objname; 2126a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_srcloc; 2127a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2128a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_bottom(iipc)) { 2129a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // At the bottom (towards main), we describe the fn at eip. 2130a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_fnname = VG_(clo_sym_offsets) 2131a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN) 2132a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : VG_(get_fnname) (eip, buf_fn, BUF_LEN); 2133a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 2134a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0 2135a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->next_inltab] 2136a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 2137a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (next_inl); 2138a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The function we are in is called by next_inl. 2139a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(snprintf)(buf_fn, BUF_LEN, "%s", next_inl->inlinedfn); 2140a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_fnname = True; 2141a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2142a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // INLINED???? 2143a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Can we compute an offset for an inlined fn call ? 2144a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Offset from what ? The beginning of the inl info ? 2145a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? But that is not necessarily the beginning of the fn 2146a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? as e.g. an inlined fn call can be in several ranges. 2147a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Currently never showing an offset. 2148a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 2149a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2150a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN); 2151a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2152a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_top(iipc)) { 2153a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The source for the highest level is in the loctab entry. 2154a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_srcloc = VG_(get_filename_linenum)( 2155a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe eip, 2156a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe buf_srcloc, BUF_LEN, 2157a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe buf_dirname, BUF_LEN, &know_dirinfo, 2158a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe &lineno 2159a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ); 2160a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 2161a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *cur_inl = iipc && iipc->cur_inltab >= 0 2162a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->cur_inltab] 2163a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 2164a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (cur_inl); 2165a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 216659e1f3c79e870a978d24add86db6d8c5450c8b63philippe know_dirinfo = False; 2167666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe // The fndn_ix and lineno for the caller of the inlined fn is in cur_inl. 2168666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe if (cur_inl->fndn_ix == 0) { 2169666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe VG_(snprintf) (buf_srcloc, BUF_LEN, "???"); 2170666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } else { 2171666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe FnDn *fndn = VG_(indexEltNumber) (iipc->di->fndnpool, 2172666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe cur_inl->fndn_ix); 2173666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe if (fndn->dirname) { 2174666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe VG_(snprintf) (buf_dirname, BUF_LEN, "%s", fndn->dirname); 2175666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe know_dirinfo = True; 2176666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } 2177666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe VG_(snprintf) (buf_srcloc, BUF_LEN, "%s", fndn->filename); 2178666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } 2179666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe lineno = cur_inl->lineno; 2180a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_srcloc = True; 2181a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 2182a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2183a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 218414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_fn [ sizeof(buf_fn)-1 ] = 0; 218514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_obj [ sizeof(buf_obj)-1 ] = 0; 218614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_srcloc [ sizeof(buf_srcloc)-1 ] = 0; 218714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_dirname[ sizeof(buf_dirname)-1 ] = 0; 218814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 2189eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_xml)) { 2190eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2191eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool human_readable = True; 21926bd9dc18c043927c1196caba20a327238a179c42florian const HChar* maybe_newline = human_readable ? "\n " : ""; 21936bd9dc18c043927c1196caba20a327238a179c42florian const HChar* maybe_newline2 = human_readable ? "\n " : ""; 2194eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2195e872fec0c1c3b478a399fdba42ac65764b53f470sewardj /* Print in XML format, dumping in as much info as we know. 2196e872fec0c1c3b478a399fdba42ac65764b53f470sewardj Ensure all tags are balanced even if the individual strings 2197e872fec0c1c3b478a399fdba42ac65764b53f470sewardj are too long. Allocate 1/10 of BUF_LEN to the object name, 2198e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 6/10s to the function name, 1/10 to the directory name and 2199e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1/10 to the file name, leaving 1/10 for all the fixed-length 2200e872fec0c1c3b478a399fdba42ac65764b53f470sewardj stuff. */ 2201eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<frame>"); 2202a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip); 2203eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2204eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_objname) { 2206eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2207eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<obj>"); 2208e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_obj); 2209eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</obj>"); 2210eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2211eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 2212eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2213eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<fn>"); 2214e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(6*BUF_LEN/10, buf_fn); 2215eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</fn>"); 2216eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2217eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 2218eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_dirinfo) { 2219eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2220eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<dir>"); 2221e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_dirname); 2222eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</dir>"); 2223eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2224eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2225eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<file>"); 2226e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_srcloc); 2227eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</file>"); 2228eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2229eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<line>"); 2230eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 2231eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2232eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</line>"); 2233eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2234eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline2); 2235eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</frame>"); 2236eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2237eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 2238eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2239eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Print for humans to read */ 22405e40abad4504416c59f0b29c1cfc8087201213a9njn // 22415e40abad4504416c59f0b29c1cfc8087201213a9njn // Possible forms: 22425e40abad4504416c59f0b29c1cfc8087201213a9njn // 22435e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (a.c:20) 22445e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in /foo/a.out) 22455e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in ???) 22465e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (in /foo/a.out) 22475e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (a.c:20) 22485e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? 22495e40abad4504416c59f0b29c1cfc8087201213a9njn // 2250a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip); 2251eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 22525e40abad4504416c59f0b29c1cfc8087201213a9njn if (know_fnname) { 2253eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_fn); 2254eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 2255eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("???"); 2256eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2257eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 2258eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" ("); 225914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Get the directory name, if any, possibly pruned, into dirname. 22601636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* dirname = NULL; 226114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (VG_(clo_n_fullpath_after) > 0) { 226214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj Int i; 226314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = buf_dirname; 226414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Remove leading prefixes from the dirname. 226514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // If user supplied --fullpath-after=foo, this will remove 226614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // a leading string which matches '.*foo' (not greedy). 226714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj for (i = 0; i < VG_(clo_n_fullpath_after); i++) { 22681636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* prefix = VG_(clo_fullpath_after)[i]; 22691636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* str = VG_(strstr)(dirname, prefix); 227014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (str) { 227114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = str + VG_(strlen)(prefix); 227214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj break; 227314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 227414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 227514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj /* remove leading "./" */ 227614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname[0] == '.' && dirname[1] == '/') 227714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname += 2; 227814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 227914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // do we have any interesting directory name to show? If so 228014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // add it in. 228114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname && dirname[0] != 0) { 228214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND(dirname); 228314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND("/"); 22845dd0190bc0ea66f8ffa7218c66f5a2e1c7b51b30bart } 2285eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_srcloc); 2286eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(":"); 2287eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 2288eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2289eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 22905e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_objname) { 22915e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in "); 22925e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(buf_obj); 22935e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 22945e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_fnname) { 22955e40abad4504416c59f0b29c1cfc8087201213a9njn // Nb: do this in two steps because "??)" is a trigraph! 22965e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in ???"); 22975e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 2298eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2299eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return buf; 2302eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2303eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND 2304eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND_ESC 2305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef BUF_LEN 2306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 230872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 2309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DWARF3 .eh_frame INFO ---*/ 2313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 231572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 231672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Gather up all the constant pieces of info needed to evaluate 231772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj a CfiExpr into one convenient struct. */ 231872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjtypedef 231972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj struct { 23203026f71684a930286186aa10fef266c304672e8fsewardj D3UnwindRegs* uregs; 23213026f71684a930286186aa10fef266c304672e8fsewardj Addr min_accessible; 23223026f71684a930286186aa10fef266c304672e8fsewardj Addr max_accessible; 232372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 232472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext; 232572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 232672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Evaluate the CfiExpr rooted at ix in exprs given the context eec. 232772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj *ok is set to False on failure, but not to True on success. The 232872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj caller must set it to True before calling. */ 2329f7183e38d6215e98043ed014cb947cf5262bdc4asewardj__attribute__((noinline)) 2330f7183e38d6215e98043ed014cb947cf5262bdc4asewardjstatic 233172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjUWord evalCfiExpr ( XArray* exprs, Int ix, 233272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext* eec, Bool* ok ) 233372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 233440628facff2285b0fce592381c6e26fdcd2a1252tom UWord w, wL, wR; 233519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj Addr a; 23363026f71684a930286186aa10fef266c304672e8fsewardj CfiExpr* e; 23373026f71684a930286186aa10fef266c304672e8fsewardj vg_assert(sizeof(Addr) == sizeof(UWord)); 23383026f71684a930286186aa10fef266c304672e8fsewardj e = VG_(indexXA)( exprs, ix ); 233972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 234040628facff2285b0fce592381c6e26fdcd2a1252tom case Cex_Unop: 234140628facff2285b0fce592381c6e26fdcd2a1252tom w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok ); 234240628facff2285b0fce592381c6e26fdcd2a1252tom if (!(*ok)) return 0; 234340628facff2285b0fce592381c6e26fdcd2a1252tom switch (e->Cex.Unop.op) { 234440628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Abs: return (Word) w < 0 ? - w : w; 234540628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Neg: return - (Word) w; 234640628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Not: return ~ w; 234740628facff2285b0fce592381c6e26fdcd2a1252tom default: goto unhandled; 234840628facff2285b0fce592381c6e26fdcd2a1252tom } 234940628facff2285b0fce592381c6e26fdcd2a1252tom /*NOTREACHED*/ 235072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 235172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok ); 235272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 235372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok ); 235472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 235572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.Binop.op) { 2356f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Add: return wL + wR; 2357f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Sub: return wL - wR; 2358f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_And: return wL & wR; 2359f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Mul: return wL * wR; 2360f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shl: return wL << wR; 2361f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shr: return wL >> wR; 2362f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Eq: return wL == wR ? 1 : 0; 2363f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0; 2364f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0; 2365f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0; 2366f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0; 2367f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ne: return wL != wR ? 1 : 0; 236872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 236972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 237072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 237172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 237272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.CfiReg.reg) { 23733026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 23743026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_IP: return eec->uregs->xip; 23753026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_SP: return eec->uregs->xsp; 23763026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_BP: return eec->uregs->xbp; 23773026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 23783026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R15: return eec->uregs->r15; 23793026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R14: return eec->uregs->r14; 2380fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R13: return eec->uregs->r13; 2381fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R12: return eec->uregs->r12; 2382ade2eddf567a868bafad9110ed92acf7373a972bsewardj case Creg_ARM_R7: return eec->uregs->r7; 2383b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2384b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_IA_IP: return eec->uregs->ia; 2385b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_IA_SP: return eec->uregs->sp; 2386b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_IA_BP: return eec->uregs->fp; 2387b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_S390_R14: return eec->uregs->lr; 23884df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 23895db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_IP: return eec->uregs->pc; 23905db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_SP: return eec->uregs->sp; 23915db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_BP: return eec->uregs->fp; 23925db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_MIPS_RA: return eec->uregs->ra; 2393cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) \ 2394cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGA_ppc64le) 2395f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2396821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_ARM64_X30: return eec->uregs->x30; 23973026f71684a930286186aa10fef266c304672e8fsewardj# else 23983026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 23993026f71684a930286186aa10fef266c304672e8fsewardj# endif 240072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 240172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 240272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 240372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 240472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return e->Cex.Const.con; 240519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cex_Deref: 240619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok ); 240719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (!(*ok)) return 0; 240819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (a < eec->min_accessible 2409720e6b71b171885281afab634ce4d667c1f262bcsewardj || a > eec->max_accessible - sizeof(UWord) + 1) { 241019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj *ok = False; 241119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return 0; 241219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj } 241319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj /* let's hope it doesn't trap! */ 241486781fabbfc019b752f9605e487cfce77b2a592atom return ML_(read_UWord)((void *)a); 241572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 241672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj goto unhandled; 241772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 241872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 241972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj unhandled: 242072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n\nevalCfiExpr: unhandled\n"); 242172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)( exprs, ix ); 242272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n"); 242372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 242472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 242572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return 0; 242672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 242772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 242872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 24295c3dba227192de63d86f65ec7d9597c132818c37philippe/* Search all the DebugInfos in the entire system, to find the DiCfSI_m 2430f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that pertains to 'ip'. 2431eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2432f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If found, set *diP to the DebugInfo in which it resides, and 24335c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP to the cfsi_m pointer in that DebugInfo's cfsi_m_pool. 243472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 24355c3dba227192de63d86f65ec7d9597c132818c37philippe If not found, set *diP to (DebugInfo*)1 and *cfsi_mP to zero. 2436f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 2437f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj__attribute__((noinline)) 2438f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void find_DiCfSI ( /*OUT*/DebugInfo** diP, 24395c3dba227192de63d86f65ec7d9597c132818c37philippe /*OUT*/DiCfSI_m** cfsi_mP, 2440f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr ip ) 2441f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 2442f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 2443f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i = -1; 2444f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2445f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_search = 0; 2446f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_steps = 0; 2447eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_search++; 2448eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2449f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("search for %#lx\n", ip); 2450eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2451f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2452f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word j; 2453eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_steps++; 2454eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Use the per-DebugInfo summary address ranges to skip 2456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inapplicable DebugInfos quickly. */ 2457f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi_used == 0) 2458eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2459f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma) 2460eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2461eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2462f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* It might be in this DebugInfo. Search it. */ 2463f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj j = ML_(search_one_cfitab)( di, ip ); 2464f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(j >= -1 && j < (Word)di->cfsi_used); 2465f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2466f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (j != -1) { 2467f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj i = j; 2468f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; /* found it */ 2469eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2470eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2471eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2472f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i == -1) { 2473f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2474f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* we didn't find it. */ 2475f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = (DebugInfo*)1; 24765c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP = 0; 2477f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2478f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 2479f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 24805c3dba227192de63d86f65ec7d9597c132818c37philippe /* found a di corresponding to ip. */ 2481f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* ensure that di is 4-aligned (at least), so it can't possibly 2482f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj be equal to (DebugInfo*)1. */ 2483f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di && VG_IS_4_ALIGNED(di)); 24845c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP = ML_(get_cfsi_m) (di, i); 24855c3dba227192de63d86f65ec7d9597c132818c37philippe if (*cfsi_mP == NULL) { 24865c3dba227192de63d86f65ec7d9597c132818c37philippe // This is a cfsi hole. Report no cfi information found. 24875c3dba227192de63d86f65ec7d9597c132818c37philippe *diP = (DebugInfo*)1; 24885c3dba227192de63d86f65ec7d9597c132818c37philippe // But we will still perform the hack below. 24895c3dba227192de63d86f65ec7d9597c132818c37philippe } else { 24905c3dba227192de63d86f65ec7d9597c132818c37philippe *diP = di; 24915c3dba227192de63d86f65ec7d9597c132818c37philippe } 2492f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2493f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Start of performance-enhancing hack: once every 64 (chosen 2494f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj hackily after profiling) successful searches, move the found 2495f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo one step closer to the start of the list. This 2496f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj makes future searches cheaper. For starting konqueror on 2497f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj amd64, this in fact reduces the total amount of searching 2498f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj done by the above find-the-right-DebugInfo loop by more than 2499f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj a factor of 20. */ 2500f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if ((n_search & 0xF) == 0) { 2501f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Move di one step closer to the start of the list. */ 2502f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj move_DebugInfo_one_step_forward( di ); 2503f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2504f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* End of performance-enhancing hack. */ 2505f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2506f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2507f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("find_DiCfSI: %lu searches, " 2508f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "%lu DebugInfos looked at\n", 2509f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_search, n_steps); 2510f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2511f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2512f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2513f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2514f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2515f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2516f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Now follows a mechanism for caching queries to find_DiCfSI, since 2517f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj they are extremely frequent on amd64-linux, during stack unwinding. 2518f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25195c3dba227192de63d86f65ec7d9597c132818c37philippe Each cache entry binds an ip value to a (di, cfsi_m*) pair. Possible 2520f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj values: 2521f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25225c3dba227192de63d86f65ec7d9597c132818c37philippe di is non-null, cfsi_m* >= 0 ==> cache slot in use, "cfsi_m*" 25235c3dba227192de63d86f65ec7d9597c132818c37philippe di is (DebugInfo*)1 ==> cache slot in use, no associated di 25245c3dba227192de63d86f65ec7d9597c132818c37philippe di is NULL ==> cache slot not in use 2525f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2526f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence simply zeroing out the entire cache invalidates all 2527f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj entries. 2528f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25295c3dba227192de63d86f65ec7d9597c132818c37philippe We can map an ip value directly to a (di, cfsi_m*) pair as 25305c3dba227192de63d86f65ec7d9597c132818c37philippe once a DebugInfo is read, adding new DiCfSI_m* is not possible 25315c3dba227192de63d86f65ec7d9597c132818c37philippe anymore, as the cfsi_m_pool is frozen once the reading is terminated. 25325c3dba227192de63d86f65ec7d9597c132818c37philippe Also, the cache is invalidated when new debuginfo is read due to 25335c3dba227192de63d86f65ec7d9597c132818c37philippe an mmap or some debuginfo is discarded due to an munmap. */ 2534eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25355c3dba227192de63d86f65ec7d9597c132818c37philippe// Prime number, giving about 6Kbytes cache on 32 bits, 25365c3dba227192de63d86f65ec7d9597c132818c37philippe// 12Kbytes cache on 64 bits. 25375c3dba227192de63d86f65ec7d9597c132818c37philippe#define N_CFSI_M_CACHE 509 2538f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2539f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 25405c3dba227192de63d86f65ec7d9597c132818c37philippe struct { Addr ip; DebugInfo* di; DiCfSI_m* cfsi_m; } 25415c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt; 2542f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25435c3dba227192de63d86f65ec7d9597c132818c37philippestatic CFSI_m_CacheEnt cfsi_m_cache[N_CFSI_M_CACHE]; 2544f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25455c3dba227192de63d86f65ec7d9597c132818c37philippestatic void cfsi_m_cache__invalidate ( void ) { 25465c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(memset)(&cfsi_m_cache, 0, sizeof(cfsi_m_cache)); 254720ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe CF_info_generation++; 2548f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2549f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 255020ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippeUInt VG_(CF_info_generation) (void) 255120ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe{ 255220ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe return CF_info_generation; 255320ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe} 2554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25555c3dba227192de63d86f65ec7d9597c132818c37philippestatic inline CFSI_m_CacheEnt* cfsi_m_cache__find ( Addr ip ) 2556f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 25575c3dba227192de63d86f65ec7d9597c132818c37philippe UWord hash = ip % N_CFSI_M_CACHE; 25585c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce = &cfsi_m_cache[hash]; 25593c9cf3442185b5891e15450d6e3058aeff6796fetom static UWord n_q = 0, n_m = 0; 2560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2561f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_q++; 2562f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && 0 == (n_q & 0x1FFFFF)) 2563f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("QQQ %lu %lu\n", n_q, n_m); 2564f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25653c9cf3442185b5891e15450d6e3058aeff6796fetom if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) { 25663c9cf3442185b5891e15450d6e3058aeff6796fetom /* found an entry in the cache .. */ 25673c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 25683c9cf3442185b5891e15450d6e3058aeff6796fetom /* not found in cache. Search and update. */ 25693c9cf3442185b5891e15450d6e3058aeff6796fetom n_m++; 25703c9cf3442185b5891e15450d6e3058aeff6796fetom ce->ip = ip; 25715c3dba227192de63d86f65ec7d9597c132818c37philippe find_DiCfSI( &ce->di, &ce->cfsi_m, ip ); 25723c9cf3442185b5891e15450d6e3058aeff6796fetom } 2573eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25743c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce->di == (DebugInfo*)1)) { 25753c9cf3442185b5891e15450d6e3058aeff6796fetom /* no DiCfSI for this address */ 25763c9cf3442185b5891e15450d6e3058aeff6796fetom return NULL; 25773c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 25783c9cf3442185b5891e15450d6e3058aeff6796fetom /* found a DiCfSI for this address */ 25793c9cf3442185b5891e15450d6e3058aeff6796fetom return ce; 2580eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 25813c9cf3442185b5891e15450d6e3058aeff6796fetom} 2582eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2583eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2584f7183e38d6215e98043ed014cb947cf5262bdc4asewardjinline 25853026f71684a930286186aa10fef266c304672e8fsewardjstatic Addr compute_cfa ( D3UnwindRegs* uregs, 25863c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible, 25875c3dba227192de63d86f65ec7d9597c132818c37philippe DebugInfo* di, DiCfSI_m* cfsi_m ) 25883c9cf3442185b5891e15450d6e3058aeff6796fetom{ 25893c9cf3442185b5891e15450d6e3058aeff6796fetom CfiExprEvalContext eec; 25903c9cf3442185b5891e15450d6e3058aeff6796fetom Addr cfa; 25913c9cf3442185b5891e15450d6e3058aeff6796fetom Bool ok; 2592eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25933c9cf3442185b5891e15450d6e3058aeff6796fetom /* Compute the CFA. */ 259472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = 0; 25955c3dba227192de63d86f65ec7d9597c132818c37philippe switch (cfsi_m->cfa_how) { 25963026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 25973026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_SPREL: 25985c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->xsp; 25993026f71684a930286186aa10fef266c304672e8fsewardj break; 26003026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_BPREL: 26015c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->xbp; 260272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 26033026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 26043026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R13REL: 26055c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r13; 260672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 26073026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R12REL: 26085c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r12; 26093026f71684a930286186aa10fef266c304672e8fsewardj break; 26103026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R11REL: 26115c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r11; 26123026f71684a930286186aa10fef266c304672e8fsewardj break; 2613fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case CFIC_ARM_R7REL: 26145c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r7; 2615fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj break; 2616b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2617b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_SPREL: 26185c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 2619b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2620b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_MEMCFAREL: 2621b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { 26225c3dba227192de63d86f65ec7d9597c132818c37philippe Addr a = uregs->sp + cfsi_m->cfa_off; 2623b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (a < min_accessible || a > max_accessible-sizeof(Addr)) 2624b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 262586781fabbfc019b752f9605e487cfce77b2a592atom cfa = ML_(read_Addr)((void *)a); 2626b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2627b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2628b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_SAME: 2629b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj cfa = uregs->fp; 2630b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2631b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_BPREL: 26325c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->fp; 2633b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 26344df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 26355db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_SPREL: 26365c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 26375db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 26385db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIR_SAME: 26395db15403e889d4db339b342bc2a824ef0bfaa654sewardj cfa = uregs->fp; 26405db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 26415db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_BPREL: 26425c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->fp; 26435db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 2644cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2645f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2646821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_SPREL: 26475c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 2648821283b2110420321fd3f60afcc799b287788c68sewardj break; 2649821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_X29REL: 26505c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->x29; 2651821283b2110420321fd3f60afcc799b287788c68sewardj break; 26523026f71684a930286186aa10fef266c304672e8fsewardj# else 26533026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 26543026f71684a930286186aa10fef266c304672e8fsewardj# endif 26553026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_EXPR: /* available on all archs */ 26567888e2204fff6e7429236b4227ed16594e7743b9sewardj if (0) { 26577888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("CFIC_EXPR: "); 26585c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppCfiExpr)(di->cfsi_exprs, cfsi_m->cfa_off); 26597888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("\n"); 26607888e2204fff6e7429236b4227ed16594e7743b9sewardj } 26613026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregs; 26627888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.min_accessible = min_accessible; 26637888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.max_accessible = max_accessible; 26647888e2204fff6e7429236b4227ed16594e7743b9sewardj ok = True; 26655c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = evalCfiExpr(di->cfsi_exprs, cfsi_m->cfa_off, &eec, &ok ); 26663c9cf3442185b5891e15450d6e3058aeff6796fetom if (!ok) return 0; 266772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 266872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 266972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 267072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 26713c9cf3442185b5891e15450d6e3058aeff6796fetom return cfa; 26723c9cf3442185b5891e15450d6e3058aeff6796fetom} 26733c9cf3442185b5891e15450d6e3058aeff6796fetom 26743c9cf3442185b5891e15450d6e3058aeff6796fetom 26753c9cf3442185b5891e15450d6e3058aeff6796fetom/* Get the call frame address (CFA) given an IP/SP/FP triple. */ 26763026f71684a930286186aa10fef266c304672e8fsewardj/* NOTE: This function may rearrange the order of entries in the 26773026f71684a930286186aa10fef266c304672e8fsewardj DebugInfo list. */ 26783c9cf3442185b5891e15450d6e3058aeff6796fetomAddr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp, 26793c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible ) 26803c9cf3442185b5891e15450d6e3058aeff6796fetom{ 26815c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce; 26823c9cf3442185b5891e15450d6e3058aeff6796fetom 26835c3dba227192de63d86f65ec7d9597c132818c37philippe ce = cfsi_m_cache__find(ip); 26843c9cf3442185b5891e15450d6e3058aeff6796fetom 26853c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 26863c9cf3442185b5891e15450d6e3058aeff6796fetom return 0; /* no info. Nothing we can do. */ 26873c9cf3442185b5891e15450d6e3058aeff6796fetom 26883026f71684a930286186aa10fef266c304672e8fsewardj /* Temporary impedance-matching kludge so that this keeps working 26893026f71684a930286186aa10fef266c304672e8fsewardj on x86-linux and amd64-linux. */ 26903026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 26913026f71684a930286186aa10fef266c304672e8fsewardj { D3UnwindRegs uregs; 26923026f71684a930286186aa10fef266c304672e8fsewardj uregs.xip = ip; 26933026f71684a930286186aa10fef266c304672e8fsewardj uregs.xsp = sp; 26943026f71684a930286186aa10fef266c304672e8fsewardj uregs.xbp = fp; 26953026f71684a930286186aa10fef266c304672e8fsewardj return compute_cfa(&uregs, 269605c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 26973026f71684a930286186aa10fef266c304672e8fsewardj } 2698b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(VGA_s390x) 2699b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { D3UnwindRegs uregs; 2700b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.ia = ip; 2701b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.sp = sp; 2702b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.fp = fp; 2703b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return compute_cfa(&uregs, 270405c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 2705b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2706f03d0b76228354fb63eb970a4e6c9fa1337d60a9dejanj#elif defined(VGA_mips32) || defined(VGA_mips64) 2707fe0b43315c344cfd07981a0826bc34614a220169dejanj { D3UnwindRegs uregs; 2708fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.pc = ip; 2709fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.sp = sp; 2710fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.fp = fp; 2711fe0b43315c344cfd07981a0826bc34614a220169dejanj return compute_cfa(&uregs, 271205c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 2713fe0b43315c344cfd07981a0826bc34614a220169dejanj } 2714b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 27153026f71684a930286186aa10fef266c304672e8fsewardj# else 27163026f71684a930286186aa10fef266c304672e8fsewardj return 0; /* indicates failure */ 27173026f71684a930286186aa10fef266c304672e8fsewardj# endif 27183c9cf3442185b5891e15450d6e3058aeff6796fetom} 27193c9cf3442185b5891e15450d6e3058aeff6796fetom 27203c9cf3442185b5891e15450d6e3058aeff6796fetom 27213026f71684a930286186aa10fef266c304672e8fsewardj/* The main function for DWARF2/3 CFI-based stack unwinding. Given a 27223026f71684a930286186aa10fef266c304672e8fsewardj set of registers in UREGS, modify it to hold the register values 27233026f71684a930286186aa10fef266c304672e8fsewardj for the previous frame, if possible. Returns True if successful. 27243026f71684a930286186aa10fef266c304672e8fsewardj If not successful, *UREGS is not changed. 27253026f71684a930286186aa10fef266c304672e8fsewardj 27263026f71684a930286186aa10fef266c304672e8fsewardj For x86 and amd64, the unwound registers are: {E,R}IP, 27273026f71684a930286186aa10fef266c304672e8fsewardj {E,R}SP, {E,R}BP. 27283026f71684a930286186aa10fef266c304672e8fsewardj 2729fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj For arm, the unwound registers are: R7 R11 R12 R13 R14 R15. 2730821283b2110420321fd3f60afcc799b287788c68sewardj 2731821283b2110420321fd3f60afcc799b287788c68sewardj For arm64, the unwound registers are: X29(FP) X30(LR) SP PC. 27323026f71684a930286186aa10fef266c304672e8fsewardj*/ 27333026f71684a930286186aa10fef266c304672e8fsewardjBool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, 27343c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, 27353c9cf3442185b5891e15450d6e3058aeff6796fetom Addr max_accessible ) 27363c9cf3442185b5891e15450d6e3058aeff6796fetom{ 27373c9cf3442185b5891e15450d6e3058aeff6796fetom DebugInfo* di; 27385c3dba227192de63d86f65ec7d9597c132818c37philippe DiCfSI_m* cfsi_m = NULL; 27393026f71684a930286186aa10fef266c304672e8fsewardj Addr cfa, ipHere = 0; 27405c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce; 2741d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj CfiExprEvalContext eec __attribute__((unused)); 27423026f71684a930286186aa10fef266c304672e8fsewardj D3UnwindRegs uregsPrev; 27433c9cf3442185b5891e15450d6e3058aeff6796fetom 27443026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 27453026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->xip; 27463026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 27473026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->r15; 2748b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2749b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj ipHere = uregsHere->ia; 27504df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 27515db15403e889d4db339b342bc2a824ef0bfaa654sewardj ipHere = uregsHere->pc; 2752cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2753f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2754821283b2110420321fd3f60afcc799b287788c68sewardj ipHere = uregsHere->pc; 27553026f71684a930286186aa10fef266c304672e8fsewardj# else 27563026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 27573026f71684a930286186aa10fef266c304672e8fsewardj# endif 27585c3dba227192de63d86f65ec7d9597c132818c37philippe ce = cfsi_m_cache__find(ipHere); 27593c9cf3442185b5891e15450d6e3058aeff6796fetom 27603c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 27613c9cf3442185b5891e15450d6e3058aeff6796fetom return False; /* no info. Nothing we can do. */ 27623c9cf3442185b5891e15450d6e3058aeff6796fetom 27633c9cf3442185b5891e15450d6e3058aeff6796fetom di = ce->di; 27645c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m = ce->cfsi_m; 27653c9cf3442185b5891e15450d6e3058aeff6796fetom 27663c9cf3442185b5891e15450d6e3058aeff6796fetom if (0) { 27675c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("found cfsi_m (but printing fake base/len): "); 27685c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppDiCfSI)(di->cfsi_exprs, 0, 0, cfsi_m); 27693c9cf3442185b5891e15450d6e3058aeff6796fetom } 27703c9cf3442185b5891e15450d6e3058aeff6796fetom 2771f7183e38d6215e98043ed014cb947cf5262bdc4asewardj VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev)); 27723c9cf3442185b5891e15450d6e3058aeff6796fetom 27733c9cf3442185b5891e15450d6e3058aeff6796fetom /* First compute the CFA. */ 27743026f71684a930286186aa10fef266c304672e8fsewardj cfa = compute_cfa(uregsHere, 27755c3dba227192de63d86f65ec7d9597c132818c37philippe min_accessible, max_accessible, di, cfsi_m); 27763c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(cfa == 0)) 27773c9cf3442185b5891e15450d6e3058aeff6796fetom return False; 277872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 277972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* Now we know the CFA, use it to roll back the registers we're 278072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj interested in. */ 2781eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2782eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define COMPUTE(_prev, _here, _how, _off) \ 2783eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 2784eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (_how) { \ 2785eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_UNKNOWN: \ 2786eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 2787eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_SAME: \ 2788eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = _here; break; \ 2789eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_MEMCFAREL: { \ 2790eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a = cfa + (Word)_off; \ 2791eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a < min_accessible \ 27929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj || a > max_accessible-sizeof(Addr)) \ 2793eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 279486781fabbfc019b752f9605e487cfce77b2a592atom _prev = ML_(read_Addr)((void *)a); \ 2795eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 2796eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2797eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_CFAREL: \ 2798eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = cfa + (Word)_off; \ 2799eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 280072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIR_EXPR: \ 280172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (0) \ 2802f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs,_off); \ 28033026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregsHere; \ 280472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.min_accessible = min_accessible; \ 280572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.max_accessible = max_accessible; \ 2806d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj Bool ok = True; \ 2807f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \ 280872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!ok) return False; \ 280972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; \ 281072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: \ 281172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); \ 2812eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2813eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 2814eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 28153026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 28165c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi_m->ra_how, cfsi_m->ra_off); 28175c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi_m->sp_how, cfsi_m->sp_off); 28185c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi_m->bp_how, cfsi_m->bp_off); 28193026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 28205c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi_m->ra_how, cfsi_m->ra_off); 28215c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi_m->r14_how, cfsi_m->r14_off); 28225c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi_m->r13_how, cfsi_m->r13_off); 28235c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi_m->r12_how, cfsi_m->r12_off); 28245c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi_m->r11_how, cfsi_m->r11_off); 28255c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi_m->r7_how, cfsi_m->r7_off); 2826b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 28275c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi_m->ra_how, cfsi_m->ra_off); 28285c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 28295c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 28304df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 28315c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 28325c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 28335c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 2834cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2835f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 28365c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 28375c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 28385c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off); 28395c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off); 28403026f71684a930286186aa10fef266c304672e8fsewardj# else 28413026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 28423026f71684a930286186aa10fef266c304672e8fsewardj# endif 2843eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2844eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef COMPUTE 2845eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 28463026f71684a930286186aa10fef266c304672e8fsewardj *uregsHere = uregsPrev; 2847eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2848eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2849eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2850eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2853c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2854c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- MSVC FPO INFO ---*/ 2855c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2856c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2857c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2858c8259b85b701d25d72aabe9dc0a8154517f96913sewardjBool VG_(use_FPO_info) ( /*MOD*/Addr* ipP, 2859c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* spP, 2860c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* fpP, 2861c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr min_accessible, 2862c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr max_accessible ) 2863c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 2864c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word i; 2865c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo* di; 2866c8259b85b701d25d72aabe9dc0a8154517f96913sewardj FPO_DATA* fpo = NULL; 2867c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr spHere; 2868c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2869c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_search = 0; 2870c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_steps = 0; 2871c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search++; 2872c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2873c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) VG_(printf)("search FPO for %#lx\n", *ipP); 2874c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2875c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2876c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_steps++; 2877c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2878c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Use the per-DebugInfo summary address ranges to skip 2879c8259b85b701d25d72aabe9dc0a8154517f96913sewardj inapplicable DebugInfos quickly. */ 2880c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (di->fpo == NULL) 2881c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2882c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma) 2883c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2884c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2885c8259b85b701d25d72aabe9dc0a8154517f96913sewardj i = ML_(search_one_fpotab)( di, *ipP ); 2886c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (i != -1) { 2887c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word j; 2888c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2889c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* debug printing only */ 2890c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("look for %#lx size %ld i %ld\n", 2891c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *ipP, di->fpo_size, i); 2892c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (j = 0; j < di->fpo_size; j++) 2893c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("[%02ld] %#x %d\n", 2894c8259b85b701d25d72aabe9dc0a8154517f96913sewardj j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize); 2895c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2896c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(i >= 0 && i < di->fpo_size); 2897c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fpo = &di->fpo[i]; 2898c8259b85b701d25d72aabe9dc0a8154517f96913sewardj break; 2899c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2900c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2901c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2902c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (fpo == NULL) 2903c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return False; 2904c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2905c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2906c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("VG_(use_FPO_info): %lu searches, " 2907c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "%lu DebugInfos looked at\n", 2908c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search, n_steps); 2909c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2910c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2911c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Start of performance-enhancing hack: once every 64 (chosen 2912c8259b85b701d25d72aabe9dc0a8154517f96913sewardj hackily after profiling) successful searches, move the found 2913c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo one step closer to the start of the list. This makes 2914c8259b85b701d25d72aabe9dc0a8154517f96913sewardj future searches cheaper. For starting konqueror on amd64, this 2915c8259b85b701d25d72aabe9dc0a8154517f96913sewardj in fact reduces the total amount of searching done by the above 2916c8259b85b701d25d72aabe9dc0a8154517f96913sewardj find-the-right-DebugInfo loop by more than a factor of 20. */ 2917c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if ((n_search & 0x3F) == 0) { 2918c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Move si one step closer to the start of the list. */ 2919c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //move_DebugInfo_one_step_forward( di ); 2920c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2921c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* End of performance-enhancing hack. */ 2922c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2923c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2924c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("found fpo: "); 2925c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //ML_(ppFPO)(fpo); 2926c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2927c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2928c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 2929c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Stack layout is: 2930c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp-> 2931c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cbRegs {%edi, %esi, %ebp, %ebx} 2932c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwLocals 2933c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return_pc 2934c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwParams 2935c8259b85b701d25d72aabe9dc0a8154517f96913sewardj prior_%esp-> 2936c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2937c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Typical code looks like: 2938c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sub $4*.cdwLocals,%esp 2939c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Alternative to above for >=4KB (and sometimes for smaller): 2940c8259b85b701d25d72aabe9dc0a8154517f96913sewardj mov $size,%eax 2941c8259b85b701d25d72aabe9dc0a8154517f96913sewardj call __chkstk # WinNT performs page-by-page probe! 2942c8259b85b701d25d72aabe9dc0a8154517f96913sewardj __chkstk is much like alloc(), except that on return 2943c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %eax= 5+ &CALL. Thus it could be used as part of 2944c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Position Independent Code to locate the Global Offset Table. 2945c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebx 2946c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebp 2947c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %esi 2948c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Other once-only instructions often scheduled >here<. 2949c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %edi 2950c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2951c8259b85b701d25d72aabe9dc0a8154517f96913sewardj If the pc is within the first .cbProlog bytes of the function, 2952c8259b85b701d25d72aabe9dc0a8154517f96913sewardj then you must disassemble to see how many registers have been pushed, 2953c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because instructions in the prolog may be scheduled for performance. 2954c8259b85b701d25d72aabe9dc0a8154517f96913sewardj The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing 2955c8259b85b701d25d72aabe9dc0a8154517f96913sewardj registers not pushed when .cbRegs < 4. This seems somewhat strange 2956c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because %ebp is the register whose usage you want to minimize, 2957c8259b85b701d25d72aabe9dc0a8154517f96913sewardj yet it is in the first half of the PUSH list. 2958c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2959c8259b85b701d25d72aabe9dc0a8154517f96913sewardj I don't know what happens when the compiler constructs an outgoing CALL. 2960c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp could move if outgoing parameters are PUSHed, and this affects 2961c8259b85b701d25d72aabe9dc0a8154517f96913sewardj traceback for errors during the PUSHes. */ 2962c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2963c8259b85b701d25d72aabe9dc0a8154517f96913sewardj spHere = *spP; 2964c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 296586781fabbfc019b752f9605e487cfce77b2a592atom *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals))); 296686781fabbfc019b752f9605e487cfce77b2a592atom *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 296786781fabbfc019b752f9605e487cfce77b2a592atom + fpo->cdwParams); 296886781fabbfc019b752f9605e487cfce77b2a592atom *fpP = ML_(read_Addr)((void *)(spHere + 4*2)); 2969c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return True; 2970c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 2971c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2972c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2973c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2974c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/ 2976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- FROM DWARF3 DEBUG INFO ---*/ 2977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2980588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Try to make p2XA(dst, fmt, args..) turn into 2981b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart VG_(xaprintf)(dst, fmt, args) without having to resort to 2982588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj vararg macros. As usual with everything to do with varargs, it's 2983588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj an ugly hack. 2984738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2985588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj //#define p2XA(dstxa, format, args...) 2986b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart // VG_(xaprintf)(dstxa, format, ##args) 2987738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 2988b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart#define p2XA VG_(xaprintf) 2989738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2990588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Add a zero-terminating byte to DST, which must be an XArray* of 2991588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj HChar. */ 2992738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void zterm_XA ( XArray* dst ) 2993738856f99eea33d86ce91dcb1d6cd5b151e307casewardj{ 2994738856f99eea33d86ce91dcb1d6cd5b151e307casewardj HChar zero = 0; 2995738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (void) VG_(addBytesToXA)( dst, &zero, 1 ); 2996738856f99eea33d86ce91dcb1d6cd5b151e307casewardj} 2997738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2998738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Evaluate the location expression/list for var, to see whether or 3000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj not data_addr falls within the variable. If so also return the 3001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset of data_addr from the start of the variable. Note that 3002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs, which supplies ip,sp,fp values, will be NULL for global 3003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables, and non-NULL for local variables. */ 3004c4431bfe04c7490ea2d74939d222d87f13f30960njnstatic Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, 30059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 3006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 3007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary* regs, 3008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3009588658b13b5ad77672f323d48fe9da0ca60b0bcbtom const DebugInfo* di ) 3010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 301150fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 3012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT var_szB; 3013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GXResult res; 3014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show = False; 30159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 3016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 3017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->gexpr); 3018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Figure out how big the variable is. */ 302050fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 302150fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 302250fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 302350fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 302450fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 302550fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 302650fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 302750fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 302850fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 302950fde23467d92281b32dd537d0d9a590263628c3sewardj 303050fde23467d92281b32dd537d0d9a590263628c3sewardj var_szB = (SizeT)mul.ul; /* NB: truncate to host word */ 3031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 3033a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ", 3034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var->name ); 30359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(pp_TyEnt_C_ishly)( tyents, var->typeR ); 3036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 3037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ignore zero-sized vars; they can never match anything. */ 3040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (var_szB == 0) { 3041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) 3042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> Fail (variable is zero sized)\n"); 3043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3046588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di ); 3047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 3049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> "); 3050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GXResult)( res ); 3051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 3052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3053eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 30543c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind == GXR_Addr 3055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && res.word <= data_addr 3056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr < res.word + var_szB) { 3057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *offset = data_addr - res.word; 3058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 3060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3065738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Format the acquired information into DN(AME)1 and DN(AME)2, which 3066738856f99eea33d86ce91dcb1d6cd5b151e307casewardj are XArray*s of HChar, that have been initialised by the caller. 3067738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Resulting strings will be zero terminated. Information is 3068738856f99eea33d86ce91dcb1d6cd5b151e307casewardj formatted in an understandable way. Not so easy. If frameNo is 3069738856f99eea33d86ce91dcb1d6cd5b151e307casewardj -1, this is assumed to be a global variable; else a local 3070738856f99eea33d86ce91dcb1d6cd5b151e307casewardj variable. */ 3071738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void format_message ( /*MOD*/XArray* /* of HChar */ dn1, 3072738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dn2, 3073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3074666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe DebugInfo* di, 3075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 3076c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT var_offset, 3077c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset, 3078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* /*UChar*/ described, 3079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int frameNo, 3080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid ) 3081eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3082738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool have_descr, have_srcloc; 3083738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool xml = VG_(clo_xml); 30841636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* vo_plural = var_offset == 1 ? "" : "s"; 30851636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* ro_plural = residual_offset == 1 ? "" : "s"; 30861636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* basetag = "auxwhat"; /* a constant */ 30871636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar tagL[32], tagR[32], xagL[32], xagR[32]; 3088666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe const HChar *fileName = ML_(fndn_ix2filename)(di, var->fndn_ix); 3089666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe // fileName will be "???" if var->fndn_ix == 0. 3090666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe // fileName will only be used if have_descr is True. 3091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3092d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj if (frameNo < -1) { 3093d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(0); /* Not allowed */ 3094d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3095d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else if (frameNo == -1) { 3096d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid == VG_INVALID_THREADID); 3097d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3098d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else /* (frameNo >= 0) */ { 3099d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid != VG_INVALID_THREADID); 3100d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3101d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj 3102738856f99eea33d86ce91dcb1d6cd5b151e307casewardj vg_assert(dn1 && dn2); 3103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(described); 3104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var && var->name); 3105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_descr = VG_(sizeXA)(described) > 0 3106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && *(UChar*)VG_(indexXA)(described,0) != '\0'; 3107666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe have_srcloc = var->fndn_ix > 0 && var->lineNo > 0; 3108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3109738856f99eea33d86ce91dcb1d6cd5b151e307casewardj tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0; 3110738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3111738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat> 3112738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat> 3113738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat> 3114738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat> 3115738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3116738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3117738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGL(_xa) p2XA(_xa, "%s", tagL) 3118738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGR(_xa) p2XA(_xa, "%s", tagR) 3119738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGL(_xa) p2XA(_xa, "%s", xagL) 3120738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGR(_xa) p2XA(_xa, "%s", xagR) 3121738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTL(_xa) p2XA(_xa, "%s", "<text>") 3122738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTR(_xa) p2XA(_xa, "%s", "</text>") 3123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ local cases ------ */ 3125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) { 3127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 3128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a", 3129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 3130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3131738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3132738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3133738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3134b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside local var \"%pS\",", 3135738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3136738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3137738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3138738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3139738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3140738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3141738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3142738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3143738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\",", 3144738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3145738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3146738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3147738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { 3151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 3152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a" 3153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 3154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3155738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3156738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3157738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3158b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside local var \"%pS\"", 3159738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3160738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3161738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3162738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3163738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3164b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d, in frame #%d of thread %d", 3165666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo, frameNo, (Int)tid ); 3166738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3167738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3168738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3169b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3170666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3171738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3172738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3173738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3174738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\"", 3175738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3176738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3177738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 3178666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo, frameNo, (Int)tid ); 3179738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && have_descr ) { 3183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 3184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2 3185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 3186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3187738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3188738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3189738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3190b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS", 3191738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3192738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3193738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3194738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3195738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3196738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3197738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3198738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3199738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3200738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s", 3201738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3202738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3203738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3204738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3205738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && have_descr ) { 3209738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3210738856f99eea33d86ce91dcb1d6cd5b151e307casewardj declared at dsyms7.c:17, in frame #1 of thread 1 */ 3211738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3212738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3213738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3214b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 3215738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3216738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3217738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3218738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3219738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3220738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3221b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d, in frame #%d of thread %d", 3222666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo, frameNo, (Int)tid ); 3223738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3224738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3225738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3226b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3227666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3228738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3229738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3230738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3231738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3232738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3233738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3234738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3235738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 3236666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo, frameNo, (Int)tid ); 3237738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ global cases ------ */ 3241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) { 3242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 3243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 3244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3245738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3246738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3247738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3248b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside global var \"%pS\"", 3249738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3250738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3251738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3252738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3253738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 3254738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3255738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { 3259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 3260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 3261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17 3262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3263738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3264738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3265738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3266b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside global var \"%pS\"", 3267738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3268738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3269738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3270738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3271738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3272b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d", 3273666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3274738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3275738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3276738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3277b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3278666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3279738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3280738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3281738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3282738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 3283738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3284738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3285738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d", 3286666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3287738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && have_descr ) { 3291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 3292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable 3294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3295738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3296738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3297738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3298b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 3299738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3300738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3301738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3302738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3303738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3304738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 3305738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3306738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3307738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3308738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3309738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3310738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (char*)(VG_(indexXA)(described,0)) ); 3311738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3312738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 3313738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && have_descr ) { 3317738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3318738856f99eea33d86ce91dcb1d6cd5b151e307casewardj a global variable declared at dsyms7.c:17 */ 3319738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3320738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3321738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3322b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 3323738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3324738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3325738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3326738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3327738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3328738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3329b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "a global variable declared at %pS:%d", 3330666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3331738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3332738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3333738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3334b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3335666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3336738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3337738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3338738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3339738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3340738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3341738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3342738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3343738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable declared at %s:%d", 3344666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3345738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 3349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3350738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Zero terminate both strings */ 3351738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn1 ); 3352738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn2 ); 3353738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3354738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGL 3355738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGR 3356738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGL 3357738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGR 3358738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTL 3359738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTR 3360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3362738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Determine if data_addr is a local variable in the frame 3364738856f99eea33d86ce91dcb1d6cd5b151e307casewardj characterised by (ip,sp,fp), and if so write its description at the 3365738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ends of DNAME{1,2}, which are XArray*s of HChar, that have been 3366738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, zero terminate both, and return True. 3367738856f99eea33d86ce91dcb1d6cd5b151e307casewardj If it's not a local variable in said frame, return False. */ 3368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 3369738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, 3370738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dname2, 3371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ip, Addr sp, Addr fp, 3373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* shown to user: */ 3374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid, Int frameNo ) 3375eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary regs; 3379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 3380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_search = 0; 3382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_steps = 0; 3383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search++; 3384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3385a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp); 3386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* first, find the DebugInfo that pertains to 'ip'. */ 3387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 3388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_steps++; 3389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. So does this text mapping bracket the ip? */ 3393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 3394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Didn't find it. Strange -- means ip is a code address outside 3398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any mapped text segment. Unlikely but not impossible -- app 3399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj could be generating code to run. */ 3400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) 3401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x1) == 0)) 3404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("consider_vars_in_frame: %u searches, " 3405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 3406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 3407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every ??? (chosen 3408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hackily after profiling) successful searches, move the found 3409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 3410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj future searches cheaper. */ 3411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0xFFFF) == 0) { 3412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Move si one step closer to the start of the list. */ 3413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( di ); 3414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* End of performance-enhancing hack. */ 3416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Work through the scopes from most deeply nested outwards, 3422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj looking for code address ranges that bracket 'ip'. The 3423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables on each such address range found are in scope right 3424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj now. Don't descend to level zero as that is the global 3425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.ip = ip; 3427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.sp = sp; 3428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.fp = fp; 3429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "for each scope, working outwards ..." */ 3431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 3432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange; 3435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* this_scope 3436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 3437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 3439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!this_scope) 3440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Find the set of variables in this scope that 3442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj bracket the program counter. */ 3443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj arange = VG_(OSetGen_LookupWithCmp)( 3444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this_scope, &ip, 3445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) 3446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 3447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) 3448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* stay sane */ 3450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= arange->aMax); 3451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must bracket the ip we asked for, else 3452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 3453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 3454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must have an attached XArray of DiVariables. */ 3455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = arange->vars; 3456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(vars); 3457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But it mustn't cover the entire address range. We only 3458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expect that to happen for the global scope (level 0), which 3459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we're not looking at here. Except, it may cover the entire 3460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address range, but in that case the vars array must be 3461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj empty. */ 3462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(! (arange->aMin == (Addr)0 3463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && arange->aMax == ~(Addr)0 3464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && VG_(sizeXA)(vars) > 0) ); 3465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 3466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 3467c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3469a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 3470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->name,arange->aMin,arange->aMax,ip); 34719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, 34729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var, ®s, 3473588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3474c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 34769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 34779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3478738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3479666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe data_addr, di, var, offset, residual_offset, 3480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, frameNo, tid ); 3481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3488eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3489eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3490738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Try to form some description of DATA_ADDR by looking at the DWARF3 349125963376a3669e7f77395d6f884bdf1f6a928966philippe debug info we have. This considers all global variables, and 8 3492738856f99eea33d86ce91dcb1d6cd5b151e307casewardj frames in the stacks of all threads. Result is written at the ends 3493738856f99eea33d86ce91dcb1d6cd5b151e307casewardj of DNAME{1,2}V, which are XArray*s of HChar, that have been 3494738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, and True is returned. If no description 3495738856f99eea33d86ce91dcb1d6cd5b151e307casewardj is created, False is returned. Regardless of the return value, 3496738856f99eea33d86ce91dcb1d6cd5b151e307casewardj DNAME{1,2}V are guaranteed to be zero terminated after the call. 3497738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3498738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Note that after the call, DNAME{1,2} may have more than one 3499738856f99eea33d86ce91dcb1d6cd5b151e307casewardj trailing zero, so callers should establish the useful text length 3500738856f99eea33d86ce91dcb1d6cd5b151e307casewardj using VG_(strlen) on the contents, rather than VG_(sizeXA) on the 3501738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray itself. 3502738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 3503738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool VG_(get_data_description)( 3504738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname1v, 3505738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname2v, 3506738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Addr data_addr 3507738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ) 3508eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# define N_FRAMES 8 3510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES]; 3511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UInt n_frames; 3512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr stack_min, stack_max; 3514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid; 3515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 3516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3519738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname1 = (XArray*)dname1v; 3520738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname2 = (XArray*)dname2v; 3521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3522a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr); 3523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* First, see if data_addr is (or is part of) a global variable. 3524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Loop over the DebugInfos we have. Check data_addr against the 3525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj outermost scope of all of them, as that should be a global 3526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 3528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* global_scope; 35299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word gs_size; 3530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero; 3531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* global_arange; 3532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* perhaps this object didn't contribute any vars at all? */ 3542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(sizeXA)( di->varinfo ) == 0) 3543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 ); 3545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_scope); 3546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gs_size = VG_(OSetGen_Size)( global_scope ); 3547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global scope might be completely empty if this 3548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj compilation unit declared locals but nothing global. */ 3549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (gs_size == 0) 3550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But if it isn't empty, then it must contain exactly one 3552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj element, which covers the entire address range. */ 3553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gs_size == 1); 3554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fish out the global scope and check it is as expected. */ 3555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj zero = 0; 3556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_arange 3557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = VG_(OSetGen_Lookup)( global_scope, &zero ); 3558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global range from (Addr)0 to ~(Addr)0 must exist */ 3559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange); 3560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange->aMin == (Addr)0 3561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && global_arange->aMax == ~(Addr)0); 3562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Any vars in this range? */ 3563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!global_arange->vars) 3564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, there are some vars in the global scope of this 3566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo. Wade through them and see if the data addresses 3567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any of them bracket data_addr. */ 3568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = global_arange->vars; 3569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)( vars ); i++) { 3570c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i ); 3572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 3573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note we use a NULL RegSummary* here. It can't make any 3574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sense for a global variable to have a location expression 3575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which depends on a SP/FP/IP value. So don't supply any. 3576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This means, if the evaluation of the location 3577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expression/list requires a register, we have to let it 3578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fail. */ 35799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, var, 3580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj NULL/* RegSummary* */, 3581588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3582c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 35849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 35859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3586738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3587666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe data_addr, di, var, offset, residual_offset, 3588d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj described, -1/*frameNo*/, 3589d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj VG_INVALID_THREADID ); 3590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3591738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3592738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, well it's not a global variable. So now let's snoop around 3599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in the stacks of all the threads. First try to figure out which 3600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj thread's stack data_addr is in. */ 3601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Perhaps it's on a thread's stack? */ 3603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = False; 3604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 3605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 3606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 3607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 3608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min - VG_STACK_REDZONE_SZB <= data_addr 3609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr <= stack_max) { 3610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = True; 3611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!found) { 3615738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3616738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We conclude data_addr is in thread tid's stack. Unwind the 3621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack to get a bunch of (ip,sp,fp) triples describing the 3622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames, and for each frame, consider the local variables. */ 3623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES, 3624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps, fps, 0/*first_ip_delta*/ ); 3625b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj 3626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_frames >= 0 && n_frames <= N_FRAMES); 3627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < n_frames; j++) { 3628738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (consider_vars_in_frame( dname1, dname2, 3629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 3630b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j], 3631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 3632738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3633738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now, it appears that gcc sometimes appears to produce 3637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj location lists whose ranges don't actually cover the call 3638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj instruction, even though the address of the variable in 3639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj question is passed as a parameter in the call. AFAICS this 3640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is simply a bug in gcc - how can the variable be claimed not 3641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exist in memory (on the stack) for the duration of a call in 3642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which its address is passed? But anyway, in the particular 3643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case I investigated (memcheck/tests/varinfo6.c, call to croak 3644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj on line 2999, local var budget declared at line 3115 3645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj appearing not to exist across the call to mainSort on line 3646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on 3647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj amd64), the variable's location list does claim it exists 3648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj starting at the first byte of the first instruction after the 3649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call instruction. So, call consider_vars_in_frame a second 3650b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj time, but this time add 1 to the IP. GDB handles this 3651b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj example with no difficulty, which leads me to believe that 3652b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj either (1) I misunderstood something, or (2) GDB has an 3653b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj equivalent kludge. */ 3654b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj if (j > 0 /* this is a non-innermost frame */ 3655738856f99eea33d86ce91dcb1d6cd5b151e307casewardj && consider_vars_in_frame( dname1, dname2, 3656b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj data_addr, 3657b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j] + 1, 3658b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj sps[j], fps[j], tid, j )) { 3659738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3660738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We didn't find anything useful. */ 3666738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3667738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# undef N_FRAMES 3670eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3671eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 36739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 36749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 36759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// Support for other kinds of queries to the Dwarf3 var info // 36769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 36779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 36789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Figure out if the variable 'var' has a location that is linearly 36809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj dependent on a stack pointer value, or a frame pointer value, and 36819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if it is, add a description of it to 'blocks'. Otherwise ignore 36829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. If 'arrays_only' is True, also ignore it unless it has an 36839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array type. */ 36849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic 36869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, 36879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 3688588658b13b5ad77672f323d48fe9da0ca60b0bcbtom Addr ip, const DebugInfo* di, DiVariable* var, 36899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 36909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 36919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; 36929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 369350fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 36949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 36959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 36969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 36989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0&&debug) 36999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("adeps: var %s\n", var->name ); 37009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 370250fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 370350fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 370450fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 370550fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 370650fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 370750fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 370850fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 370950fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 371050fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 37119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in arrays */ 37139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR ); 37149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 37159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 37169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 37179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; /* perhaps we should complain in this case? */ 37189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 37199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) 37209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; 37219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR); 37239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %s\n", var->name);} 37249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Do some test evaluations of the variable's location expression, 37269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in order to guess whether it is sp-relative, fp-relative, or 37279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj none. A crude hack, which can be interpreted roughly as finding 37289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the first derivative of the location expression w.r.t. the 37299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj supplied frame and stack pointer values. */ 37309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 37319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 37329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 6 * 1024; 3733588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 37369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 37379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 7 * 1024; 3738588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 6 * 1024; 37419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 37429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3743588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 7 * 1024; 37469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 37479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3748588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_sp_7k.kind); 37519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_6k.kind); 37529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_7k.kind); 37539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37543c9cf3442185b5891e15450d6e3058aeff6796fetom if (res_sp_6k.kind == GXR_Addr) { 37559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj StackBlock block; 37569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 37579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord sp_delta = res_sp_7k.word - res_sp_6k.word; 37589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord fp_delta = res_fp_7k.word - res_fp_6k.word; 37599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(sp_delta == 0 || sp_delta == 1024); 37609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(fp_delta == 0 || fp_delta == 1024); 37619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 0) { 37639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* depends neither on sp nor fp, so it can't be a stack 37649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj local. Ignore it. */ 37659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 37669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 37679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 1024 && fp_delta == 0) { 37689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 37699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3770588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37713c9cf3442185b5891e15450d6e3058aeff6796fetom tl_assert(res.kind == GXR_Addr); 37729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 37739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (sp) %s\n", 377450fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 37759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 377650fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 37779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = True; 37789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 37799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 37809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 37819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 37829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 37839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 37849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 37859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 37869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 1024) { 37879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 37889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3789588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37903c9cf3442185b5891e15450d6e3058aeff6796fetom tl_assert(res.kind == GXR_Addr); 37919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 37929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (FP) %s\n", 379350fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 37949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 379550fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 37969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = False; 37979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 37989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 37999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 38009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 38019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 38029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 38039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else { 38059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(0); 38069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 38099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an XArray of StackBlock which describe the stack (auto) blocks 38129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for this ip. The caller is expected to free the XArray at some 38139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj point. If 'arrays_only' is True, only array-typed blocks are 38149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned; otherwise blocks of all types are returned. */ 38159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of StackBlock */ 38179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) 38189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 38199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 38209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word i; 38219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 38229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 38239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1", 38259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 38269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(StackBlock) ); 38279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_search = 0; 38299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_steps = 0; 38309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search++; 38319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 38329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip); 38339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* first, find the DebugInfo that pertains to 'ip'. */ 38349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 38359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_steps++; 38369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* text segment missing? unlikely, but handle it .. */ 38379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->text_present || di->text_size == 0) 38389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 38399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok. So does this text mapping bracket the ip? */ 38409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 38419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 38429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Didn't find it. Strange -- means ip is a code address outside 38459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj of any mapped text segment. Unlikely but not impossible -- app 38469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj could be generating code to run. */ 38479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di) 38489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 38499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0 && ((n_search & 0x1) == 0)) 38519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, " 38529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "%u DebugInfos looked at\n", 38539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search, n_steps); 38549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Start of performance-enhancing hack: once every ??? (chosen 38559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hackily after profiling) successful searches, move the found 38569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo one step closer to the start of the list. This makes 38579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj future searches cheaper. */ 38589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ((n_search & 0xFFFF) == 0) { 38599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Move si one step closer to the start of the list. */ 38609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj move_DebugInfo_one_step_forward( di ); 38619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* End of performance-enhancing hack. */ 38639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 38659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 38669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 38679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Work through the scopes from most deeply nested outwards, 38699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj looking for code address ranges that bracket 'ip'. The 38709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj variables on each such address range found are in scope right 38719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj now. Don't descend to level zero as that is the global 38729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj scope. */ 38739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* "for each scope, working outwards ..." */ 38759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 38769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* vars; 38779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word j; 38789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* arange; 38799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* this_scope 38809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 38819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 38829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 38839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!this_scope) 38849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 38859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Find the set of variables in this scope that 38869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj bracket the program counter. */ 38879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arange = VG_(OSetGen_LookupWithCmp)( 38889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this_scope, &ip, 38899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) 38909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ); 38919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!arange) 38929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 38939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* stay sane */ 38949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= arange->aMax); 38959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must bracket the ip we asked for, else 38969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 38979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 38989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must have an attached XArray of DiVariables. */ 38999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vars = arange->vars; 39009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(vars); 39019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* But it mustn't cover the entire address range. We only 39029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj expect that to happen for the global scope (level 0), which 39039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj we're not looking at here. Except, it may cover the entire 39049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj address range, but in that case the vars array must be 39059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj empty. */ 39069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(! (arange->aMin == (Addr)0 39079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && arange->aMax == ~(Addr)0 39089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && VG_(sizeXA)(vars) > 0) ); 39099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 39109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 39119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 39129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 39139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->name,arange->aMin,arange->aMax,ip); 39149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj analyse_deps( res, di->admin_tyents, ip, 3915588658b13b5ad77672f323d48fe9da0ca60b0bcbtom di, var, arrays_only ); 39169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; 39209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 39219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an array of GlobalBlock which describe the global blocks owned 39249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj by the shared object characterised by the given di_handle. Asserts 39259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if the handle is invalid. The caller is responsible for freeing 39269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the array at some point. If 'arrays_only' is True, only 39279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array-typed blocks are returned; otherwise blocks of all types are 39289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned. */ 39299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of GlobalBlock */ 39319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, 39329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 39339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 39349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 39359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 39379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* gvars; /* XArray* of GlobalBlock */ 39389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nScopes, scopeIx; 39399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* The first thing to do is find the DebugInfo that 39419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj pertains to 'di_handle'. */ 39429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di_handle > 0); 39439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 39449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->handle == di_handle) 39459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 39469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If this fails, we were unable to find any DebugInfo with the 39499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj given handle. This is considered an error on the part of the 39509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj caller. */ 39519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di != NULL); 39529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll put the collected variables in here. */ 39549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1", 39559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), sizeof(GlobalBlock) ); 39569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gvars); 39579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 39599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 39609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 39619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll iterate over all the variables we can find, even if 39639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it seems senseless to visit stack-allocated variables */ 39649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over all scopes */ 39659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nScopes = VG_(sizeXA)( di->varinfo ); 39669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (scopeIx = 0; scopeIx < nScopes; scopeIx++) { 39679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each (code) address range at the current scope */ 39699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* range; 39709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* /* of DiAddrInfo */ scope 39719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx ); 39729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(scope); 39739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(OSetGen_ResetIter)(scope); 39749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while ( (range = VG_(OSetGen_Next)(scope)) ) { 39759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each variable in the current address range */ 39779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nVars, varIx; 39789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(range->vars); 39799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nVars = VG_(sizeXA)( range->vars ); 39809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (varIx = 0; varIx < nVars; varIx++) { 39819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 39839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 398450fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 39859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GlobalBlock gb; 39869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 39879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = VG_(indexXA)( range->vars, varIx ); 39889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 39899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name ); 39909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Now figure out if this variable has a constant address 39929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (that is, independent of FP, SP, phase of moon, etc), 39939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj and if so, what the address is. Any variable with a 39949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj constant address is deemed to be a global so we collect 39959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 39969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); 39979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("\n"); } 3998588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_trivial_GX)( var->gexpr, di ); 39999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Not a constant address => not interesting */ 40013c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind != GXR_Addr) { 40029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("FAIL\n"); 40039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 40049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 40059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, it's a constant address. See if we want to collect 40079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 40089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("%#lx\n", res.word); 40099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 401150fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(di->admin_tyents, var->typeR); 40129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 401350fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 401450fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. 401550fde23467d92281b32dd537d0d9a590263628c3sewardj ML_(addVar) should have rejected it. */ 401650fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 401750fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 401850fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 401950fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a 402050fde23467d92281b32dd537d0d9a590263628c3sewardj host word safely (without loss of info). */ 40219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in 40239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arrays */ 40249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, 40259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR ); 40269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 40279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 40289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 40299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; /* perhaps we should complain in this case? */ 40309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 40329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) continue; 40339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so collect it! */ 40359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 40369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di->soname); 40379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("XXXX %s %s %d\n", var->name, 4038666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe ML_(fndn_ix2filename)(di, var->fndn_ix), 4039666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe var->lineNo); 40409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)(&gb, 0, sizeof(gb)); 40419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.addr = res.word; 404250fde23467d92281b32dd537d0d9a590263628c3sewardj gb.szB = (SizeT)mul.ul; 40439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.isVec = isVec; 40449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1); 40459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1); 40469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.name[ sizeof(gb.name)-1 ] == 0); 40479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0); 40489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( gvars, &gb ); 40509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (varIx = 0; varIx < nVars; varIx++) */ 40529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */ 40549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */ 40569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 40589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 40599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 4061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DebugInfo accessor functions ---*/ 4063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4065e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di) 4066eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 4068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return debugInfo_list; 4069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->next; 4070eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4071eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4072e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_text_avma)(const DebugInfo* di) 4073eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_avma : 0; 4075eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4076eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4077e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di) 4078eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_size : 0; 4080eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4081eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 40823898022a7d74a227d6a35102faaedd420ed3a1c1bartAddr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di) 40833898022a7d74a227d6a35102faaedd420ed3a1c1bart{ 40843898022a7d74a227d6a35102faaedd420ed3a1c1bart return di->bss_present ? di->bss_avma : 0; 40853898022a7d74a227d6a35102faaedd420ed3a1c1bart} 40863898022a7d74a227d6a35102faaedd420ed3a1c1bart 40873898022a7d74a227d6a35102faaedd420ed3a1c1bartSizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di) 40883898022a7d74a227d6a35102faaedd420ed3a1c1bart{ 40893898022a7d74a227d6a35102faaedd420ed3a1c1bart return di->bss_present ? di->bss_size : 0; 40903898022a7d74a227d6a35102faaedd420ed3a1c1bart} 40913898022a7d74a227d6a35102faaedd420ed3a1c1bart 4092e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di) 4093092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4094092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_avma : 0; 4095092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4096092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4097e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di) 4098092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4099092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_size : 0; 4100092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4101092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4102e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di) 4103092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4104092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_avma : 0; 4105092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4106092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4107e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di) 4108092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4109092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_size : 0; 4110092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4111092b6268cc4a38ae9ee41d1e3355937536ddc579bart 411268347837b3d82e48f85daff33ec7ba528891e4e7bartAddr VG_(DebugInfo_get_got_avma)(const DebugInfo* di) 411368347837b3d82e48f85daff33ec7ba528891e4e7bart{ 411468347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_avma : 0; 411568347837b3d82e48f85daff33ec7ba528891e4e7bart} 411668347837b3d82e48f85daff33ec7ba528891e4e7bart 411768347837b3d82e48f85daff33ec7ba528891e4e7bartSizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di) 411868347837b3d82e48f85daff33ec7ba528891e4e7bart{ 411968347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_size : 0; 412068347837b3d82e48f85daff33ec7ba528891e4e7bart} 412168347837b3d82e48f85daff33ec7ba528891e4e7bart 41221636d33c13958b9c0e7d3059cdd5005746418eb2florianconst HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di) 4123eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->soname; 4125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4126eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 41271636d33c13958b9c0e7d3059cdd5005746418eb2florianconst HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di) 4128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4129a5acac39bf3be7546222b1316faee5ee524be0d1sewardj return di->fsm.filename; 4130eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4131eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4132e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjPtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di) 4133bbec7728efefaa650970dd1f0282b77040287133sewardj{ 4134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_bias : 0; 4135bbec7728efefaa650970dd1f0282b77040287133sewardj} 4136bbec7728efefaa650970dd1f0282b77040287133sewardj 4137e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjInt VG_(DebugInfo_syms_howmany) ( const DebugInfo *si ) 4138eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4139eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab_used; 4140eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4141eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4142e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjvoid VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, 4143e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Int idx, 41444cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/SymAVMAs* avmas, 41454cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/UInt* size, 41464cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/HChar** pri_name, 41474cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/HChar*** sec_names, 41484cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/Bool* isText, 41494cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/Bool* isIFunc ) 4150eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4151eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(idx >= 0 && idx < si->symtab_used); 41524cace66777ca9ee73ea156210c04e9d4cc178395philippe if (avmas) *avmas = si->symtab[idx].avmas; 4153a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (size) *size = si->symtab[idx].size; 4154a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (pri_name) *pri_name = si->symtab[idx].pri_name; 415519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian if (sec_names) *sec_names = (HChar **)si->symtab[idx].sec_names; // FIXME 4156a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isText) *isText = si->symtab[idx].isText; 4157a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isIFunc) *isIFunc = si->symtab[idx].isIFunc; 4158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- SectKind query functions ---*/ 4163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Convert a VgSectKind to a string, which must be copied if you want 4166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to change it. */ 4167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst HChar* VG_(pp_SectKind)( VgSectKind kind ) 4168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj switch (kind) { 4170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectUnknown: return "Unknown"; 4171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectText: return "Text"; 4172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectData: return "Data"; 4173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectBSS: return "BSS"; 4174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectGOT: return "GOT"; 4175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectPLT: return "PLT"; 4176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectOPD: return "OPD"; 41775706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj case Vg_SectGOTPLT: return "GOTPLT"; 4178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj default: vg_assert(0); 4179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Given an address 'a', make a guess of which section of which object 4183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj it comes from. If name is non-NULL, then the last n_name-1 4184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characters of the object's name is put in name[0 .. n_name-2], and 4185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] is set to zero (guaranteed zero terminated). */ 4186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 41871636d33c13958b9c0e7d3059cdd5005746418eb2florianVgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/HChar* name, SizeT n_name, 4188e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Addr a) 4189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 4191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VgSectKind res = Vg_SectUnknown; 4192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 4194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 4196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)( 4197e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld " 4198e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "data=%#lx,%ld bss=%#lx,%ld\n", 4199a5acac39bf3be7546222b1316faee5ee524be0d1sewardj a, di, di->fsm.filename, 4200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->got_avma, di->got_size, 4201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->plt_avma, di->plt_size, 4202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma, di->data_size, 4203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->bss_avma, di->bss_size); 4204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 4206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 4207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->text_avma && a < di->text_avma + di->text_size) { 4208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectText; 4209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->data_present 4212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 4213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->data_avma && a < di->data_avma + di->data_size) { 4214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 4215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->sdata_present 4218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 4219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { 4220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 4221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->bss_present 4224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 4225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { 4226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectBSS; 4227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 42295706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj if (di->sbss_present 42305706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 42315706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) { 42325706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj res = Vg_SectBSS; 42335706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj break; 42345706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj } 4235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->plt_present 4236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->plt_size > 0 4237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { 4238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectPLT; 4239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->got_present 4242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->got_size > 0 4243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->got_avma && a < di->got_avma + di->got_size) { 4244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectGOT; 4245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4247092b6268cc4a38ae9ee41d1e3355937536ddc579bart if (di->gotplt_present 4248092b6268cc4a38ae9ee41d1e3355937536ddc579bart && di->gotplt_size > 0 4249092b6268cc4a38ae9ee41d1e3355937536ddc579bart && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) { 4250092b6268cc4a38ae9ee41d1e3355937536ddc579bart res = Vg_SectGOTPLT; 4251092b6268cc4a38ae9ee41d1e3355937536ddc579bart break; 4252092b6268cc4a38ae9ee41d1e3355937536ddc579bart } 4253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->opd_present 4254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->opd_size > 0 4255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { 4256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectOPD; 4257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* we could also check for .eh_frame, if anyone really cares */ 4260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( (di == NULL && res == Vg_SectUnknown) 4263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (di != NULL && res != Vg_SectUnknown) ); 4264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (name) { 4266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_name >= 8); 4268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4269a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di && di->fsm.filename) { 4270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int i, j; 4271a5acac39bf3be7546222b1316faee5ee524be0d1sewardj Int fnlen = VG_(strlen)(di->fsm.filename); 4272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int start_at = 1 + fnlen - n_name; 4273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (start_at < 0) start_at = 0; 4274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(start_at < fnlen); 4275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i = start_at; j = 0; 4276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 4277d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(j >= 0 && j < n_name); 4278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(i >= 0 && i <= fnlen); 4279a5acac39bf3be7546222b1316faee5ee524be0d1sewardj name[j] = di->fsm.filename[i]; 4280a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fsm.filename[i] == 0) break; 4281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i++; j++; 4282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4283d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(i == fnlen); 4284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 4285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)(name, n_name, "%s", "???"); 4286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] = 0; 4289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return res; 4292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4293eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4294eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4295eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 4296eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 4297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 4298