107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe/*--------------------------------------------------------------------*/ 307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe/*--- Obtaining information about an address. ---*/ 407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe/*--- m_addrinfo.c ---*/ 507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe/*--------------------------------------------------------------------*/ 607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe/* 807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe This file is part of Valgrind, a dynamic binary instrumentation 907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe framework. 1007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 11ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2008-2017 OpenWorks Ltd 1207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe info@open-works.co.uk 1307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 1407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe This program is free software; you can redistribute it and/or 1507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe modify it under the terms of the GNU General Public License as 1607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe published by the Free Software Foundation; either version 2 of the 1707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe License, or (at your option) any later version. 1807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 1907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe This program is distributed in the hope that it will be useful, but 2007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe WITHOUT ANY WARRANTY; without even the implied warranty of 2107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 2207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe General Public License for more details. 2307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 2407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe You should have received a copy of the GNU General Public License 2507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe along with this program; if not, write to the Free Software 2607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 2707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 02111-1307, USA. 2807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 2907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe The GNU General Public License is contained in the file COPYING. 3007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe*/ 3107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 3207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_basics.h" 33d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe#include "pub_core_clientstate.h" 3407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_libcassert.h" 3507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_libcbase.h" 3607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_libcprint.h" 3707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_xarray.h" 3807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_debuginfo.h" 3907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_execontext.h" 4007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_addrinfo.h" 4107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_mallocfree.h" 4207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_machine.h" 4307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_core_options.h" 447e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe#include "pub_core_threadstate.h" 4518d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe#include "pub_core_stacktrace.h" 467e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe#include "pub_core_stacks.h" 477e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe#include "pub_core_aspacemgr.h" 487e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 497e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe/* Returns the tid whose stack includes the address a. 507e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe If not found, returns VG_INVALID_THREADID. */ 517e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippestatic ThreadId find_tid_with_stack_containing (Addr a) 527e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe{ 537e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ThreadId tid; 547e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe Addr start, end; 557e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 567e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe start = 0; 577e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe end = 0; 587e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe VG_(stack_limits)(a, &start, &end); 597e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe if (start == end) { 607e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe // No stack found 617e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe vg_assert (start == 0 && end == 0); 627e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe return VG_INVALID_THREADID; 637e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe } 647e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 657e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe /* Stack limits found. Search the tid to which this stack belongs. */ 667e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe vg_assert (start <= a); 677e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe vg_assert (a <= end); 687e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 697e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe /* The stack end (highest accessible byte) is for sure inside the 'active' 707e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe part of the stack of the searched tid. 717e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe So, scan all 'active' stacks with VG_(thread_stack_reset_iter) ... */ 727e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe { 737e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe Addr stack_min, stack_max; 747e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 757e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe VG_(thread_stack_reset_iter)(&tid); 767e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 777e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe if (stack_min <= end && end <= stack_max) 787e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe return tid; 797e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe } 807e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe } 817e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 827e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe /* We can arrive here if a stack was registered with wrong bounds 837e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe (e.g. end above the highest addressable byte) 847e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe and/or if the thread for the registered stack is dead, but 857e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe the stack was not unregistered. */ 867e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe return VG_INVALID_THREADID; 877e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe} 8807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 8907c08527f05caeb0062b42ca9a58ee774ec5fba1philippevoid VG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai ) 9007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe{ 9107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VgSectKind sect; 9207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 9307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* -- Perhaps the variable type/location data describes it? -- */ 9407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Variable.descr1 9507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe = VG_(newXA)( VG_(malloc), "mc.da.descr1", 9607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(free), sizeof(HChar) ); 9707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Variable.descr2 9807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe = VG_(newXA)( VG_(malloc), "mc.da.descr2", 9907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(free), sizeof(HChar) ); 10007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 10107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe (void) VG_(get_data_description)( ai->Addr.Variable.descr1, 10207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Variable.descr2, a ); 103ad4e979f408239dabbaae955d8ffcb84a51a5c85florian /* If there's nothing in descr1/2, free them. Why is it safe to 10407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(indexXA) at zero here? Because VG_(get_data_description) 10507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe guarantees to zero terminate descr1/2 regardless of the outcome 10607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe of the call. So there's always at least one element in each XA 10707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe after the call. 10807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe */ 10907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr1, 0 ))) { 11007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(deleteXA)( ai->Addr.Variable.descr1 ); 11107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Variable.descr1 = NULL; 11207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 11307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr2, 0 ))) { 11407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(deleteXA)( ai->Addr.Variable.descr2 ); 11507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Variable.descr2 = NULL; 11607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 11707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* Assume (assert) that VG_(get_data_description) fills in descr1 11807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe before it fills in descr2 */ 11907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (ai->Addr.Variable.descr1 == NULL) 12007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe vg_assert(ai->Addr.Variable.descr2 == NULL); 12107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* So did we get lucky? */ 12207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (ai->Addr.Variable.descr1 != NULL) { 12307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->tag = Addr_Variable; 12407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe return; 12507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 12607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* -- Have a look at the low level data symbols - perhaps it's in 12707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe there. -- */ 12846cc04521acf2827eb33310fadc119bf2dc039e4florian const HChar *name; 12907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (VG_(get_datasym_and_offset)( 13046cc04521acf2827eb33310fadc119bf2dc039e4florian a, &name, 13107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe &ai->Addr.DataSym.offset )) { 13246cc04521acf2827eb33310fadc119bf2dc039e4florian ai->Addr.DataSym.name = VG_(strdup)("mc.da.dsname", name); 13307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->tag = Addr_DataSym; 13407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe return; 13507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 13607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* -- Perhaps it's on a thread's stack? -- */ 13718d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe { 1387e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ThreadId tid; 13918d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe Addr stack_min, stack_max; 14018d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe VG_(thread_stack_reset_iter)(&tid); 14118d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 14218d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe if (stack_min - VG_STACK_REDZONE_SZB <= a && a <= stack_max) { 14318d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe Addr ips[VG_(clo_backtrace_size)], 14418d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe sps[VG_(clo_backtrace_size)]; 14518d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe UInt n_frames; 14618d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe UInt f; 14718d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe 14818d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe ai->tag = Addr_Stack; 1490c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe VG_(initThreadInfo)(&ai->Addr.Stack.tinfo); 1500c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe ai->Addr.Stack.tinfo.tid = tid; 15118d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe ai->Addr.Stack.IP = 0; 15218d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe ai->Addr.Stack.frameNo = -1; 1537e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ai->Addr.Stack.stackPos = StackPos_stacked; 1547e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ai->Addr.Stack.spoffset = 0; // Unused. 15518d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe /* It is on thread tid stack. Build a stacktrace, and 15618d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe find the frame sp[f] .. sp[f+1] where the address is. 15718d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe Store the found frameNo and the corresponding IP in 15818d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe the description. 15918d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe When description is printed, IP will be translated to 16018d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe the function name containing IP. 16118d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe Before accepting to describe addr with sp[f] .. sp[f+1], 16218d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe we verify the sp looks sane: reasonably sized frame, 16318d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe inside the stack. 16418d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe We could check the ABI required alignment for sp (what is it?) 16518d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe is respected, except for the innermost stack pointer ? */ 16618d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe n_frames = VG_(get_StackTrace)( tid, ips, VG_(clo_backtrace_size), 16718d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe sps, NULL, 0/*first_ip_delta*/ ); 16818d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe for (f = 0; f < n_frames-1; f++) { 16918d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe if (sps[f] <= a && a < sps[f+1] 17018d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe && sps[f+1] - sps[f] <= 0x4000000 // 64 MB, arbitrary 17118d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe && sps[f+1] <= stack_max 17218d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe && sps[f] >= stack_min - VG_STACK_REDZONE_SZB) { 17318d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe ai->Addr.Stack.frameNo = f; 17418d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe ai->Addr.Stack.IP = ips[f]; 17518d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe break; 17618d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe } 17718d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe } 17818d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe return; 17918d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe } 18007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 18107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 18207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 18307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* -- Maybe it is in one of the m_mallocfree.c arenas. -- */ 18407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe { 18507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe AddrArenaInfo aai; 18607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(describe_arena_addr) ( a, &aai ); 18707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (aai.name != NULL) { 18807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->tag = Addr_Block; 18907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (aai.aid == VG_AR_CLIENT) 19007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.block_kind 19107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe = aai.free ? Block_ClientArenaFree : Block_ClientArenaMallocd; 19207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe else 19307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.block_kind 19407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe = aai.free 19507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ? Block_ValgrindArenaFree : Block_ValgrindArenaMallocd; 19607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.block_desc = aai.name; 19707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.block_szB = aai.block_szB; 19807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.rwoffset = aai.rwoffset; 19907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.allocated_at = VG_(null_ExeContext)(); 2000c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo); 20107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.freed_at = VG_(null_ExeContext)(); 20207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe return; 20307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 20407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 20507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 20607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* -- last ditch attempt at classification -- */ 207e08950b4ce5a3f5d75a7279548f975cd6207dc74florian sect = VG_(DebugInfo_sect_kind)( &name, a); 20807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (sect != Vg_SectUnknown) { 20907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->tag = Addr_SectKind; 210dd2382088a3a598420286caa68e98f168a88bee3philippe ai->Addr.SectKind.objname = VG_(strdup)("mc.da.dsname", name); 21107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.SectKind.kind = sect; 21207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe return; 21307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 2147e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 2157e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe /* -- and yet another last ditch attempt at classification -- */ 2167e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe /* If the address is in a stack between the stack bottom (highest byte) 2177e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe and the current stack ptr, it will have been already described above. 2187e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe But maybe it is in a stack, but below the stack ptr (typical 2197e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe for a 'use after return' or in the stack guard page (thread stack 2207e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe too small). */ 2217e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe { 2227e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ThreadId tid; 223d099e51e1159ef5c27e066ddacc26b1866ec8e83philippe StackPos stackPos = StackPos_stacked; 224d099e51e1159ef5c27e066ddacc26b1866ec8e83philippe // Default init to StackPos_stacked, to silence gcc warning. 225ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes // We assert this value is overridden if a stack descr is produced. 2267e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 2277e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe // First try to find a tid with stack containing a 2287e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe tid = find_tid_with_stack_containing (a); 2297e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe if (tid != VG_INVALID_THREADID) { 2307e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe /* Should be below stack pointer, as if it is >= SP, it 2317e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe will have been described as StackPos_stacked above. */ 2327e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe stackPos = StackPos_below_stack_ptr; 2337e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe } else { 2347e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe /* Try to find a stack with guard page containing a. 2357e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe For this, check if a is in a page mapped without r, w and x. */ 2367e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe const NSegment *seg = VG_(am_find_nsegment) (a); 2377e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe if (seg != NULL && seg->kind == SkAnonC 2387e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe && !seg->hasR && !seg->hasW && !seg->hasX) { 2397e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe /* This looks a plausible guard page. Check if a is close to 2407e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe the start of stack (lowest byte). */ 2417e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe tid = find_tid_with_stack_containing (VG_PGROUNDUP(a+1)); 2427e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe if (tid != VG_INVALID_THREADID) 2437e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe stackPos = StackPos_guard_page; 2447e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe } 2457e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe } 2467e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 2477e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe if (tid != VG_INVALID_THREADID) { 2487e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ai->tag = Addr_Stack; 2497e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe VG_(initThreadInfo)(&ai->Addr.Stack.tinfo); 2507e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ai->Addr.Stack.tinfo.tid = tid; 2517e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ai->Addr.Stack.IP = 0; 2527e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ai->Addr.Stack.frameNo = -1; 253d099e51e1159ef5c27e066ddacc26b1866ec8e83philippe vg_assert (stackPos != StackPos_stacked); 2547e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ai->Addr.Stack.stackPos = stackPos; 2557e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe vg_assert (a < VG_(get_SP)(tid)); 2567e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ai->Addr.Stack.spoffset = a - VG_(get_SP)(tid); 2577e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe return; 2587e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe } 2597e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe } 2607e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 261f7ec77f53fd09a5682dbe6db049efe0746df7948philippe /* -- and yet another last ditch attempt at classification -- */ 262f7ec77f53fd09a5682dbe6db049efe0746df7948philippe /* Try to find a segment belonging to the client. */ 263f7ec77f53fd09a5682dbe6db049efe0746df7948philippe { 264f7ec77f53fd09a5682dbe6db049efe0746df7948philippe const NSegment *seg = VG_(am_find_nsegment) (a); 265d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe 266d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe /* Special case to detect the brk data segment. */ 267d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe if (seg != NULL 2688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(VGO_solaris) 2698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj && (seg->kind == SkAnonC || seg->kind == SkFileC) 2708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#else 271d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe && seg->kind == SkAnonC 2728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif /* VGO_solaris */ 273d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe && VG_(brk_limit) >= seg->start 274d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe && VG_(brk_limit) <= seg->end+1) { 275d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe /* Address a is in a Anon Client segment which contains 276d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe VG_(brk_limit). So, this segment is the brk data segment 277d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe as initimg-linux.c:setup_client_dataseg maps an anonymous 278d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe segment followed by a reservation, with one reservation 279d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe page that will never be used by syswrap-generic.c:do_brk, 280d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe when increasing VG_(brk_limit). 281d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe So, the brk data segment will never be merged with the 282d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe next segment, and so an address in that area will 283d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe either be in the brk data segment, or in the unmapped 284d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe part of the brk data segment reservation. */ 285d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe ai->tag = Addr_BrkSegment; 286d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe ai->Addr.BrkSegment.brk_limit = VG_(brk_limit); 287d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe return; 288d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe } 289d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe 290f7ec77f53fd09a5682dbe6db049efe0746df7948philippe if (seg != NULL 291f7ec77f53fd09a5682dbe6db049efe0746df7948philippe && (seg->kind == SkAnonC 292f7ec77f53fd09a5682dbe6db049efe0746df7948philippe || seg->kind == SkFileC 293f7ec77f53fd09a5682dbe6db049efe0746df7948philippe || seg->kind == SkShmC)) { 294f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->tag = Addr_SegmentKind; 295f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.segkind = seg->kind; 296f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.filename = NULL; 297f7ec77f53fd09a5682dbe6db049efe0746df7948philippe if (seg->kind == SkFileC) 298d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian ai->Addr.SegmentKind.filename 299d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian = VG_(strdup)("mc.da.skfname", VG_(am_get_filename)(seg)); 300f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.hasR = seg->hasR; 301f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.hasW = seg->hasW; 302f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.hasX = seg->hasX; 303f7ec77f53fd09a5682dbe6db049efe0746df7948philippe return; 304f7ec77f53fd09a5682dbe6db049efe0746df7948philippe } 305f7ec77f53fd09a5682dbe6db049efe0746df7948philippe } 306f7ec77f53fd09a5682dbe6db049efe0746df7948philippe 30707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* -- Clueless ... -- */ 30807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->tag = Addr_Unknown; 30907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe return; 31007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe} 31107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 3120c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippevoid VG_(initThreadInfo) (ThreadInfo *tinfo) 3130c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe{ 3140c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe tinfo->tid = 0; 3150c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe tinfo->tnr = 0; 3160c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe} 3170c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe 31807c08527f05caeb0062b42ca9a58ee774ec5fba1philippevoid VG_(clear_addrinfo) ( AddrInfo* ai) 31907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe{ 32007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe switch (ai->tag) { 3210af05d465f338f7009ccb1172c61f00e06ddb58aphilippe case Addr_Undescribed: 3220af05d465f338f7009ccb1172c61f00e06ddb58aphilippe break; 3230af05d465f338f7009ccb1172c61f00e06ddb58aphilippe 32407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_Unknown: 3250af05d465f338f7009ccb1172c61f00e06ddb58aphilippe break; 32607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 32707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_Stack: 3280af05d465f338f7009ccb1172c61f00e06ddb58aphilippe break; 32907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 33007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_Block: 33107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 33207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 33307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_DataSym: 33446cc04521acf2827eb33310fadc119bf2dc039e4florian VG_(free)(ai->Addr.DataSym.name); 33507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 33607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 33707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_Variable: 33807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (ai->Addr.Variable.descr1 != NULL) { 33907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(deleteXA)( ai->Addr.Variable.descr1 ); 34007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Variable.descr1 = NULL; 34107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 34207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (ai->Addr.Variable.descr2 != NULL) { 34307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(deleteXA)( ai->Addr.Variable.descr2 ); 34407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Variable.descr2 = NULL; 34507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 34607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 34707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 34807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_SectKind: 349e08950b4ce5a3f5d75a7279548f975cd6207dc74florian VG_(free)(ai->Addr.SectKind.objname); 35007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 35107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 352d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe case Addr_BrkSegment: 353d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe break; 354d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe 355f7ec77f53fd09a5682dbe6db049efe0746df7948philippe case Addr_SegmentKind: 356f7ec77f53fd09a5682dbe6db049efe0746df7948philippe VG_(free)(ai->Addr.SegmentKind.filename); 357f7ec77f53fd09a5682dbe6db049efe0746df7948philippe break; 358f7ec77f53fd09a5682dbe6db049efe0746df7948philippe 35907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe default: 36007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(core_panic)("VG_(clear_addrinfo)"); 36107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 36207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 36307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->tag = Addr_Undescribed; 36407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe} 36507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 36607c08527f05caeb0062b42ca9a58ee774ec5fba1philippestatic Bool is_arena_BlockKind(BlockKind bk) 36707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe{ 36807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe switch (bk) { 36907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Block_Mallocd: 37007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Block_Freed: 37107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Block_MempoolChunk: 37207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Block_UserG: return False; 37307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 37407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Block_ClientArenaMallocd: 37507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Block_ClientArenaFree: 37607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Block_ValgrindArenaMallocd: 37707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Block_ValgrindArenaFree: return True; 37807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 37907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe default: vg_assert (0); 38007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 38107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe} 38207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 3830c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippestatic const HChar* opt_tnr_prefix (ThreadInfo tinfo) 3840c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe{ 3850c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe if (tinfo.tnr != 0) 3860c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe return "#"; 3870c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe else 3880c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe return ""; 3890c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe} 3900c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe 3910c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippestatic UInt tnr_else_tid (ThreadInfo tinfo) 3920c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe{ 3930c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe if (tinfo.tnr != 0) 3940c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe return tinfo.tnr; 3950c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe else 3960c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe return tinfo.tid; 3970c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe} 3980c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe 399f7ec77f53fd09a5682dbe6db049efe0746df7948philippestatic const HChar* pp_SegKind ( SegKind sk ) 400f7ec77f53fd09a5682dbe6db049efe0746df7948philippe{ 401f7ec77f53fd09a5682dbe6db049efe0746df7948philippe switch (sk) { 402f7ec77f53fd09a5682dbe6db049efe0746df7948philippe case SkAnonC: return "anonymous"; 403f7ec77f53fd09a5682dbe6db049efe0746df7948philippe case SkFileC: return "mapped file"; 404f7ec77f53fd09a5682dbe6db049efe0746df7948philippe case SkShmC: return "shared memory"; 405f7ec77f53fd09a5682dbe6db049efe0746df7948philippe default: vg_assert(0); 406f7ec77f53fd09a5682dbe6db049efe0746df7948philippe } 407f7ec77f53fd09a5682dbe6db049efe0746df7948philippe} 408f7ec77f53fd09a5682dbe6db049efe0746df7948philippe 409518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic void pp_addrinfo_WRK ( Addr a, const AddrInfo* ai, Bool mc, 410518850bf0da07ed3e2244e307268ae0fd80e93a8florian Bool maybe_gcc ) 41107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe{ 41207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe const HChar* xpre = VG_(clo_xml) ? " <auxwhat>" : " "; 41307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe const HChar* xpost = VG_(clo_xml) ? "</auxwhat>" : ""; 41407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 41507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe vg_assert (!maybe_gcc || mc); // maybe_gcc can only be given in mc mode. 41607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 41707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe switch (ai->tag) { 4180af05d465f338f7009ccb1172c61f00e06ddb58aphilippe case Addr_Undescribed: 4190af05d465f338f7009ccb1172c61f00e06ddb58aphilippe VG_(core_panic)("mc_pp_AddrInfo Addr_Undescribed"); 4200af05d465f338f7009ccb1172c61f00e06ddb58aphilippe 42107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_Unknown: 42207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (maybe_gcc) { 423a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(emit)( "%sAddress 0x%lx is just below the stack ptr. " 42407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe "To suppress, use: --workaround-gcc296-bugs=yes%s\n", 425a5e06c36bf9d93461bc8c4351e960888020ea1c4florian xpre, a, xpost ); 42607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } else { 427a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(emit)( "%sAddress 0x%lx " 42807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe "is not stack'd, malloc'd or %s%s\n", 429a5e06c36bf9d93461bc8c4351e960888020ea1c4florian xpre, a, 43007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe mc ? "(recently) free'd" : "on a free list", 43107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xpost ); 43207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 43307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 43407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 43507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_Stack: 436a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(emit)( "%sAddress 0x%lx is on thread %s%u's stack%s\n", 437a5e06c36bf9d93461bc8c4351e960888020ea1c4florian xpre, a, 4380c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe opt_tnr_prefix (ai->Addr.Stack.tinfo), 4390c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe tnr_else_tid (ai->Addr.Stack.tinfo), 4400c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe xpost ); 44118d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe if (ai->Addr.Stack.frameNo != -1 && ai->Addr.Stack.IP != 0) { 44246cc04521acf2827eb33310fadc119bf2dc039e4florian const HChar *fn; 44318d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe Bool hasfn; 44410ef725f1e8e9f1615c483555348eb75b69c4713florian const HChar *file; 44518d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe Bool hasfile; 44618d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe UInt linenum; 44718d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe Bool haslinenum; 44818d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe PtrdiffT offset; 44918d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe 45018d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe if (VG_(get_inst_offset_in_function)( ai->Addr.Stack.IP, 45118d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe &offset)) 45218d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe haslinenum = VG_(get_linenum) (ai->Addr.Stack.IP - offset, 45318d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe &linenum); 45418d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe else 45518d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe haslinenum = False; 45618d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe 45710ef725f1e8e9f1615c483555348eb75b69c4713florian hasfile = VG_(get_filename)(ai->Addr.Stack.IP, &file); 45810ef725f1e8e9f1615c483555348eb75b69c4713florian 45910ef725f1e8e9f1615c483555348eb75b69c4713florian HChar strlinenum[16] = ""; // large enough 46010ef725f1e8e9f1615c483555348eb75b69c4713florian if (hasfile && haslinenum) 461a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(sprintf)(strlinenum, "%u", linenum); 46218d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe 46346cc04521acf2827eb33310fadc119bf2dc039e4florian hasfn = VG_(get_fnname)(ai->Addr.Stack.IP, &fn); 46446cc04521acf2827eb33310fadc119bf2dc039e4florian 46518d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe if (hasfn || hasfile) 466a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(emit)( "%sin frame #%d, created by %ps (%ps:%s)%s\n", 46718d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe xpre, 46818d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe ai->Addr.Stack.frameNo, 46918d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe hasfn ? fn : "???", 47010ef725f1e8e9f1615c483555348eb75b69c4713florian hasfile ? file : "???", strlinenum, 47118d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe xpost ); 47218d6f4ec1b86057e1a906db1a1d31c89472fb1adphilippe } 4737e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe switch (ai->Addr.Stack.stackPos) { 4747e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe case StackPos_stacked: break; // nothing more to say 4757e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 4767e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe case StackPos_below_stack_ptr: 4777e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe case StackPos_guard_page: 4787e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe VG_(emit)("%s%s%ld bytes below stack pointer%s\n", 4797e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe xpre, 4807e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe ai->Addr.Stack.stackPos == StackPos_guard_page ? 4817e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe "In stack guard protected page, " : "", 4827e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe - ai->Addr.Stack.spoffset, 4837e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe xpost); 4847e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe // Note: we change the sign of spoffset as the message speaks 4857e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe // about the nr of bytes below stack pointer. 4867e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe break; 4877e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe 4887e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe default: vg_assert(0); 4897e3b3f23b41ae75ceb6306ea3e15f110bbbf3dd6philippe } 49007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 49107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 49207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_Block: { 49307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe SizeT block_szB = ai->Addr.Block.block_szB; 49407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe PtrdiffT rwoffset = ai->Addr.Block.rwoffset; 49507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe SizeT delta; 49607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe const HChar* relative; 49707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 49807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (rwoffset < 0) { 49907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe delta = (SizeT)(-rwoffset); 50007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe relative = "before"; 50107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } else if (rwoffset >= block_szB) { 50207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe delta = rwoffset - block_szB; 50307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe relative = "after"; 50407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } else { 50507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe delta = rwoffset; 50607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe relative = "inside"; 50707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 50807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (is_arena_BlockKind (ai->Addr.Block.block_kind)) 50907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(emit)( 51007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe "%sAddress 0x%lx is %'lu bytes %s a%s block of size %'lu" 51107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe " in arena \"%s\"%s\n", 51207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xpre, 51307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe a, delta, 51407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe relative, 51507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.block_kind==Block_ClientArenaMallocd 51607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe || ai->Addr.Block.block_kind==Block_ValgrindArenaMallocd 51707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ? "" : "n unallocated", 51807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe block_szB, 51907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.block_desc, // arena name 52007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xpost 52107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ); 52207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe else 52307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(emit)( 52407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe "%sAddress 0x%lx is %'lu bytes %s a %s of size %'lu %s%s\n", 52507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xpre, 52607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe a, delta, 52707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe relative, 52807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.block_desc, 52907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe block_szB, 53007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.Block.block_kind==Block_Mallocd ? "alloc'd" 53107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe : ai->Addr.Block.block_kind==Block_Freed ? "free'd" 53207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe : "client-defined", 53307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xpost 53407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ); 53507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (ai->Addr.Block.block_kind==Block_Mallocd) { 53607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(pp_ExeContext)(ai->Addr.Block.allocated_at); 537e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert (ai->Addr.Block.freed_at == VG_(null_ExeContext)()); 53807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 53907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe else if (ai->Addr.Block.block_kind==Block_Freed) { 54007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(pp_ExeContext)(ai->Addr.Block.freed_at); 54107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (ai->Addr.Block.allocated_at != VG_(null_ExeContext)()) { 54207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(emit)( 5430c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe "%sBlock was alloc'd at%s\n", 54407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xpre, 54507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xpost 54607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ); 54707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(pp_ExeContext)(ai->Addr.Block.allocated_at); 54807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 54907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 55007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe else if (ai->Addr.Block.block_kind==Block_MempoolChunk 55107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe || ai->Addr.Block.block_kind==Block_UserG) { 55207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe // client-defined 55307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(pp_ExeContext)(ai->Addr.Block.allocated_at); 554e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert (ai->Addr.Block.freed_at == VG_(null_ExeContext)()); 55507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* Nb: cannot have a freed_at, as a freed client-defined block 55607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe has a Block_Freed block_kind. */ 55707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } else { 55807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe // Client or Valgrind arena. At least currently, we never 55907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe // have stacktraces for these. 560e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert (ai->Addr.Block.allocated_at == VG_(null_ExeContext)()); 561e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert (ai->Addr.Block.freed_at == VG_(null_ExeContext)()); 56207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 5630c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe if (ai->Addr.Block.alloc_tinfo.tnr || ai->Addr.Block.alloc_tinfo.tid) 5640c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe VG_(emit)( 565a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "%sBlock was alloc'd by thread %s%u%s\n", 5660c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe xpre, 5670c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe opt_tnr_prefix (ai->Addr.Block.alloc_tinfo), 5680c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe tnr_else_tid (ai->Addr.Block.alloc_tinfo), 5690c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe xpost 5700c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe ); 57107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 57207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 57307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 57407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_DataSym: 575a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(emit)( "%sAddress 0x%lx is %llu bytes " 576a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "inside data symbol \"%ps\"%s\n", 577a5e06c36bf9d93461bc8c4351e960888020ea1c4florian xpre, a, 57807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe (ULong)ai->Addr.DataSym.offset, 57907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.DataSym.name, 58007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xpost ); 58107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 58207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 58307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_Variable: 58407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe /* Note, no need for XML tags here, because descr1/2 will 58507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe already have <auxwhat> or <xauxwhat>s on them, in XML 58607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe mode. */ 58707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (ai->Addr.Variable.descr1) 58807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(emit)( "%s%s\n", 58907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(clo_xml) ? " " : " ", 59007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe (HChar*)VG_(indexXA)(ai->Addr.Variable.descr1, 0) ); 59107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (ai->Addr.Variable.descr2) 59207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(emit)( "%s%s\n", 59307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(clo_xml) ? " " : " ", 59407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe (HChar*)VG_(indexXA)(ai->Addr.Variable.descr2, 0) ); 59507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 59607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 59707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe case Addr_SectKind: 598a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(emit)( "%sAddress 0x%lx is in the %ps segment of %ps%s\n", 599a5e06c36bf9d93461bc8c4351e960888020ea1c4florian xpre, a, 60007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(pp_SectKind)(ai->Addr.SectKind.kind), 60107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe ai->Addr.SectKind.objname, 60207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xpost ); 603a7cea052061af7ffa79d06feb69d7d129c5bf0efphilippe if (ai->Addr.SectKind.kind == Vg_SectText) { 604a7cea052061af7ffa79d06feb69d7d129c5bf0efphilippe /* To better describe the address in a text segment, 605a7cea052061af7ffa79d06feb69d7d129c5bf0efphilippe pp a dummy stacktrace made of this single address. */ 606a7cea052061af7ffa79d06feb69d7d129c5bf0efphilippe VG_(pp_StackTrace)( &a, 1 ); 607a7cea052061af7ffa79d06feb69d7d129c5bf0efphilippe } 60807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 60907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 610d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe case Addr_BrkSegment: 611d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe if (a < ai->Addr.BrkSegment.brk_limit) 612a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(emit)( "%sAddress 0x%lx is in the brk data segment" 613a5e06c36bf9d93461bc8c4351e960888020ea1c4florian " 0x%lx-0x%lx%s\n", 614a5e06c36bf9d93461bc8c4351e960888020ea1c4florian xpre, a, 615a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(brk_base), 616a5e06c36bf9d93461bc8c4351e960888020ea1c4florian ai->Addr.BrkSegment.brk_limit - 1, 617d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe xpost ); 618d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe else 619a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(emit)( "%sAddress 0x%lx is %lu bytes after " 620d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe "the brk data segment limit" 621a5e06c36bf9d93461bc8c4351e960888020ea1c4florian " 0x%lx%s\n", 622a5e06c36bf9d93461bc8c4351e960888020ea1c4florian xpre, a, 623d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe a - ai->Addr.BrkSegment.brk_limit, 624a5e06c36bf9d93461bc8c4351e960888020ea1c4florian ai->Addr.BrkSegment.brk_limit, 625d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe xpost ); 626d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe break; 627d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe 628f7ec77f53fd09a5682dbe6db049efe0746df7948philippe case Addr_SegmentKind: 629a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(emit)( "%sAddress 0x%lx is in " 630a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "a %s%s%s %s%s%ps segment%s\n", 631f7ec77f53fd09a5682dbe6db049efe0746df7948philippe xpre, 632a5e06c36bf9d93461bc8c4351e960888020ea1c4florian a, 633f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.hasR ? "r" : "-", 634f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.hasW ? "w" : "-", 635f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.hasX ? "x" : "-", 636f7ec77f53fd09a5682dbe6db049efe0746df7948philippe pp_SegKind(ai->Addr.SegmentKind.segkind), 637f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.filename ? 638f7ec77f53fd09a5682dbe6db049efe0746df7948philippe " " : "", 639f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.filename ? 640f7ec77f53fd09a5682dbe6db049efe0746df7948philippe ai->Addr.SegmentKind.filename : "", 641f7ec77f53fd09a5682dbe6db049efe0746df7948philippe xpost ); 642f7ec77f53fd09a5682dbe6db049efe0746df7948philippe break; 643f7ec77f53fd09a5682dbe6db049efe0746df7948philippe 64407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe default: 645a4ca4fef8c189e861492e1e2b36b52ba3fca1725florian VG_(core_panic)("mc_pp_AddrInfo"); 64607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 64707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe} 64807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 649518850bf0da07ed3e2244e307268ae0fd80e93a8florianvoid VG_(pp_addrinfo) ( Addr a, const AddrInfo* ai ) 65007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe{ 65107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe pp_addrinfo_WRK (a, ai, False /*mc*/, False /*maybe_gcc*/); 65207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe} 65307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 654518850bf0da07ed3e2244e307268ae0fd80e93a8florianvoid VG_(pp_addrinfo_mc) ( Addr a, const AddrInfo* ai, Bool maybe_gcc ) 65507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe{ 65607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe pp_addrinfo_WRK (a, ai, True /*mc*/, maybe_gcc); 65707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe} 65807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 65907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 66007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe/*--------------------------------------------------------------------*/ 66107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe/*--- end m_addrinfo.c ---*/ 66207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe/*--------------------------------------------------------------------*/ 663