1eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
2eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/*--------------------------------------------------------------------*/
3eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/*--- Obtaining information about an address.                      ---*/
4eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/*---                                                 m_addrinfo.c ---*/
5eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/*--------------------------------------------------------------------*/
6eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
7eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/*
8eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   This file is part of Valgrind, a dynamic binary instrumentation
9eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   framework.
10eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
11eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   Copyright (C) 2008-2013 OpenWorks Ltd
12eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      info@open-works.co.uk
13eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
14eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   This program is free software; you can redistribute it and/or
15eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   modify it under the terms of the GNU General Public License as
16eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   published by the Free Software Foundation; either version 2 of the
17eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   License, or (at your option) any later version.
18eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
19eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   This program is distributed in the hope that it will be useful, but
20eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   WITHOUT ANY WARRANTY; without even the implied warranty of
21eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   General Public License for more details.
23eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
24eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   You should have received a copy of the GNU General Public License
25eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   along with this program; if not, write to the Free Software
26eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   02111-1307, USA.
28eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
29eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   The GNU General Public License is contained in the file COPYING.
30eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov*/
31eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
32eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_basics.h"
33eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_libcassert.h"
34eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_libcbase.h"
35eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_libcprint.h"
36eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_xarray.h"
37eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_debuginfo.h"
38eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_execontext.h"
39eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_addrinfo.h"
40eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_mallocfree.h"
41eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_machine.h"
42eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_options.h"
43eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
44eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid VG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai )
45eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{
46eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   ThreadId   tid;
47eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   Addr       stack_min, stack_max;
48eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   VgSectKind sect;
49eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
50eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   /* -- Perhaps the variable type/location data describes it? -- */
51eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   ai->Addr.Variable.descr1
52eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      = VG_(newXA)( VG_(malloc), "mc.da.descr1",
53eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    VG_(free), sizeof(HChar) );
54eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   ai->Addr.Variable.descr2
55eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      = VG_(newXA)( VG_(malloc), "mc.da.descr2",
56eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    VG_(free), sizeof(HChar) );
57eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
58eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   (void) VG_(get_data_description)( ai->Addr.Variable.descr1,
59eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                                     ai->Addr.Variable.descr2, a );
60eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   /* If there's nothing in descr1/2, free them.  Why is it safe to to
61eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(indexXA) at zero here?  Because VG_(get_data_description)
62eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      guarantees to zero terminate descr1/2 regardless of the outcome
63eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      of the call.  So there's always at least one element in each XA
64eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      after the call.
65eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   */
66eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr1, 0 ))) {
67eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(deleteXA)( ai->Addr.Variable.descr1 );
68eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      ai->Addr.Variable.descr1 = NULL;
69eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
70eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr2, 0 ))) {
71eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(deleteXA)( ai->Addr.Variable.descr2 );
72eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      ai->Addr.Variable.descr2 = NULL;
73eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
74eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   /* Assume (assert) that VG_(get_data_description) fills in descr1
75eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      before it fills in descr2 */
76eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   if (ai->Addr.Variable.descr1 == NULL)
77eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      vg_assert(ai->Addr.Variable.descr2 == NULL);
78eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   /* So did we get lucky? */
79eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   if (ai->Addr.Variable.descr1 != NULL) {
80eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      ai->tag = Addr_Variable;
81eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      return;
82eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
83eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   /* -- Have a look at the low level data symbols - perhaps it's in
84eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      there. -- */
85eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   VG_(memset)( &ai->Addr.DataSym.name,
86eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                0, sizeof(ai->Addr.DataSym.name));
87eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   if (VG_(get_datasym_and_offset)(
88eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov             a, &ai->Addr.DataSym.name[0],
89eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov             sizeof(ai->Addr.DataSym.name)-1,
90eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov             &ai->Addr.DataSym.offset )) {
91eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      ai->tag = Addr_DataSym;
92eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      vg_assert( ai->Addr.DataSym.name
93eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    [ sizeof(ai->Addr.DataSym.name)-1 ] == 0);
94eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      return;
95eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
96eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   /* -- Perhaps it's on a thread's stack? -- */
97eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   VG_(thread_stack_reset_iter)(&tid);
98eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
99eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      if (stack_min - VG_STACK_REDZONE_SZB <= a && a <= stack_max) {
100eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         ai->tag            = Addr_Stack;
101eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         ai->Addr.Stack.tid = tid;
102eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         return;
103eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      }
104eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
105eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
106eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   /* -- Maybe it is in one of the m_mallocfree.c arenas. --  */
107eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   {
108eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      AddrArenaInfo aai;
109eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(describe_arena_addr) ( a, &aai );
110eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      if (aai.name != NULL) {
111eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         ai->tag = Addr_Block;
112eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (aai.aid == VG_AR_CLIENT)
113eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            ai->Addr.Block.block_kind
114eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               = aai.free ? Block_ClientArenaFree : Block_ClientArenaMallocd;
115eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         else
116eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            ai->Addr.Block.block_kind
117eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               = aai.free
118eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                  ? Block_ValgrindArenaFree :  Block_ValgrindArenaMallocd;
119eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         ai->Addr.Block.block_desc = aai.name;
120eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         ai->Addr.Block.block_szB = aai.block_szB;
121eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         ai->Addr.Block.rwoffset = aai.rwoffset;
122eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         ai->Addr.Block.allocated_at = VG_(null_ExeContext)();
123eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         ai->Addr.Block.freed_at = VG_(null_ExeContext)();
124eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         return;
125eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      }
126eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
127eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
128eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   /* -- last ditch attempt at classification -- */
129eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   vg_assert( sizeof(ai->Addr.SectKind.objname) > 4 );
130eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   VG_(memset)( &ai->Addr.SectKind.objname,
131eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                0, sizeof(ai->Addr.SectKind.objname));
132eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   VG_(strcpy)( ai->Addr.SectKind.objname, "???" );
133eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   sect = VG_(DebugInfo_sect_kind)( &ai->Addr.SectKind.objname[0],
134eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                                    sizeof(ai->Addr.SectKind.objname)-1, a);
135eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   if (sect != Vg_SectUnknown) {
136eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      ai->tag = Addr_SectKind;
137eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      ai->Addr.SectKind.kind = sect;
138eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      vg_assert( ai->Addr.SectKind.objname
139eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    [ sizeof(ai->Addr.SectKind.objname)-1 ] == 0);
140eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      return;
141eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
142eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   /* -- Clueless ... -- */
143eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   ai->tag = Addr_Unknown;
144eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   return;
145eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
146eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
147eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid VG_(clear_addrinfo) ( AddrInfo* ai)
148eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{
149eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   switch (ai->tag) {
150eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_Unknown:
151eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov          break;
152eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
153eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_Stack:
154eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov          break;
155eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
156eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_Block:
157eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
158eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
159eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_DataSym:
160eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
161eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
162eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_Variable:
163eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (ai->Addr.Variable.descr1 != NULL) {
164eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(deleteXA)( ai->Addr.Variable.descr1 );
165eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            ai->Addr.Variable.descr1 = NULL;
166eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         }
167eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (ai->Addr.Variable.descr2 != NULL) {
168eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(deleteXA)( ai->Addr.Variable.descr2 );
169eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            ai->Addr.Variable.descr2 = NULL;
170eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         }
171eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
172eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
173eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_SectKind:
174eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
175eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
176eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      default:
177eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         VG_(core_panic)("VG_(clear_addrinfo)");
178eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
179eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
180eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   ai->tag = Addr_Undescribed;
181eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
182eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
183eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstatic Bool is_arena_BlockKind(BlockKind bk)
184eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{
185eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   switch (bk) {
186eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Block_Mallocd:
187eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Block_Freed:
188eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Block_MempoolChunk:
189eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Block_UserG:                return False;
190eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
191eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Block_ClientArenaMallocd:
192eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Block_ClientArenaFree:
193eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Block_ValgrindArenaMallocd:
194eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Block_ValgrindArenaFree:    return True;
195eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
196eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      default:                         vg_assert (0);
197eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
198eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
199eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
200eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstatic void pp_addrinfo_WRK ( Addr a, AddrInfo* ai, Bool mc, Bool maybe_gcc )
201eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{
202eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   const HChar* xpre  = VG_(clo_xml) ? "  <auxwhat>" : " ";
203eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   const HChar* xpost = VG_(clo_xml) ? "</auxwhat>"  : "";
204eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
205eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   vg_assert (!maybe_gcc || mc); // maybe_gcc can only be given in mc mode.
206eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
207eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   switch (ai->tag) {
208eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_Unknown:
209eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (maybe_gcc) {
210eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(emit)( "%sAddress 0x%llx is just below the stack ptr.  "
211eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       "To suppress, use: --workaround-gcc296-bugs=yes%s\n",
212eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       xpre, (ULong)a, xpost );
213eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov	 } else {
214eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(emit)( "%sAddress 0x%llx "
215eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       "is not stack'd, malloc'd or %s%s\n",
216eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       xpre,
217eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       (ULong)a,
218eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       mc ? "(recently) free'd" : "on a free list",
219eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       xpost );
220eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         }
221eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
222eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
223eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_Stack:
224eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         VG_(emit)( "%sAddress 0x%llx is on thread %d's stack%s\n",
225eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    xpre, (ULong)a, ai->Addr.Stack.tid, xpost );
226eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
227eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
228eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_Block: {
229eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         SizeT    block_szB = ai->Addr.Block.block_szB;
230eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         PtrdiffT rwoffset  = ai->Addr.Block.rwoffset;
231eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         SizeT    delta;
232eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         const    HChar* relative;
233eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
234eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (rwoffset < 0) {
235eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            delta    = (SizeT)(-rwoffset);
236eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            relative = "before";
237eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         } else if (rwoffset >= block_szB) {
238eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            delta    = rwoffset - block_szB;
239eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            relative = "after";
240eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         } else {
241eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            delta    = rwoffset;
242eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            relative = "inside";
243eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         }
244eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (is_arena_BlockKind (ai->Addr.Block.block_kind))
245eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(emit)(
246eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               "%sAddress 0x%lx is %'lu bytes %s a%s block of size %'lu"
247eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               " in arena \"%s\"%s\n",
248eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               xpre,
249eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               a, delta,
250eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               relative,
251eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               ai->Addr.Block.block_kind==Block_ClientArenaMallocd
252eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                 || ai->Addr.Block.block_kind==Block_ValgrindArenaMallocd
253eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                 ? "" : "n unallocated",
254eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               block_szB,
255eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               ai->Addr.Block.block_desc,  // arena name
256eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               xpost
257eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            );
258eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         else
259eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(emit)(
260eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               "%sAddress 0x%lx is %'lu bytes %s a %s of size %'lu %s%s\n",
261eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               xpre,
262eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               a, delta,
263eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               relative,
264eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               ai->Addr.Block.block_desc,
265eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               block_szB,
266eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               ai->Addr.Block.block_kind==Block_Mallocd ? "alloc'd"
267eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               : ai->Addr.Block.block_kind==Block_Freed ? "free'd"
268eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                                                        : "client-defined",
269eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               xpost
270eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            );
271eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (ai->Addr.Block.block_kind==Block_Mallocd) {
272eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(pp_ExeContext)(ai->Addr.Block.allocated_at);
273eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            tl_assert (ai->Addr.Block.freed_at == VG_(null_ExeContext)());
274eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         }
275eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         else if (ai->Addr.Block.block_kind==Block_Freed) {
276eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(pp_ExeContext)(ai->Addr.Block.freed_at);
277eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            if (ai->Addr.Block.allocated_at != VG_(null_ExeContext)()) {
278eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               VG_(emit)(
279eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                  "%s block was alloc'd at%s\n",
280eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                  xpre,
281eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                  xpost
282eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               );
283eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               VG_(pp_ExeContext)(ai->Addr.Block.allocated_at);
284eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            }
285eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         }
286eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         else if (ai->Addr.Block.block_kind==Block_MempoolChunk
287eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                  || ai->Addr.Block.block_kind==Block_UserG) {
288eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            // client-defined
289eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(pp_ExeContext)(ai->Addr.Block.allocated_at);
290eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            tl_assert (ai->Addr.Block.freed_at == VG_(null_ExeContext)());
291eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            /* Nb: cannot have a freed_at, as a freed client-defined block
292eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov               has a Block_Freed block_kind. */
293eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         } else {
294eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            // Client or Valgrind arena. At least currently, we never
295eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            // have stacktraces for these.
296eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            tl_assert (ai->Addr.Block.allocated_at == VG_(null_ExeContext)());
297eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            tl_assert (ai->Addr.Block.freed_at == VG_(null_ExeContext)());
298eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         }
299eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
300eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
301eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      }
302eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
303eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_DataSym:
304eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         VG_(emit)( "%sAddress 0x%llx is %llu bytes "
305eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    "inside data symbol \"%pS\"%s\n",
306eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    xpre,
307eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    (ULong)a,
308eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    (ULong)ai->Addr.DataSym.offset,
309eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    ai->Addr.DataSym.name,
310eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    xpost );
311eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
312eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
313eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_Variable:
314eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         /* Note, no need for XML tags here, because descr1/2 will
315eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            already have <auxwhat> or <xauxwhat>s on them, in XML
316eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            mode. */
317eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (ai->Addr.Variable.descr1)
318eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(emit)( "%s%s\n",
319eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       VG_(clo_xml) ? "  " : " ",
320eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       (HChar*)VG_(indexXA)(ai->Addr.Variable.descr1, 0) );
321eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (ai->Addr.Variable.descr2)
322eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(emit)( "%s%s\n",
323eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       VG_(clo_xml) ? "  " : " ",
324eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                       (HChar*)VG_(indexXA)(ai->Addr.Variable.descr2, 0) );
325eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
326eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
327eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      case Addr_SectKind:
328eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         VG_(emit)( "%sAddress 0x%llx is in the %pS segment of %pS%s\n",
329eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    xpre,
330eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    (ULong)a,
331eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    VG_(pp_SectKind)(ai->Addr.SectKind.kind),
332eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    ai->Addr.SectKind.objname,
333eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    xpost );
334eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         break;
335eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
336eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      default:
337eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         VG_(tool_panic)("mc_pp_AddrInfo");
338eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
339eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
340eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
341eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid VG_(pp_addrinfo) ( Addr a, AddrInfo* ai )
342eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{
343eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   pp_addrinfo_WRK (a, ai, False /*mc*/, False /*maybe_gcc*/);
344eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
345eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
346eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid VG_(pp_addrinfo_mc) ( Addr a, AddrInfo* ai, Bool maybe_gcc )
347eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{
348eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   pp_addrinfo_WRK (a, ai, True /*mc*/, maybe_gcc);
349eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
350eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
351eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
352eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/*--------------------------------------------------------------------*/
353eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/*--- end                                             m_addrinfo.c ---*/
354eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/*--------------------------------------------------------------------*/
355