blob: 16eb0769ed27c38133be68a04d4759cd577634bd [file] [log] [blame]
philippef5774342014-05-03 11:12:50 +00001
2/*--------------------------------------------------------------------*/
3/*--- Address Description. ---*/
4/*--- hg_addrdescr.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Helgrind, a Valgrind tool for detecting errors
9 in threaded programs.
10
11 Copyright (C) 2007-2012 OpenWorks Ltd
12 info@open-works.co.uk
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31#include "pub_tool_basics.h"
32#include "pub_tool_libcbase.h"
33#include "pub_tool_libcprint.h"
34#include "pub_tool_libcassert.h"
35#include "pub_tool_xarray.h"
36#include "pub_tool_execontext.h"
37#include "pub_tool_debuginfo.h"
38#include "pub_tool_threadstate.h"
39
40#include "hg_basics.h"
41#include "hg_addrdescr.h" /* self */
42
43void HG_(init_AddrDescr) ( AddrDescr* ad ) {
44 VG_(memset)(ad, 0, sizeof(*ad) );
45}
46
47void HG_(describe_addr) ( Addr a, /*OUT*/AddrDescr* ad )
48{
49 tl_assert(!ad->hctxt);
50 tl_assert(!ad->descr1);
51 tl_assert(!ad->descr2);
52
53 /* First, see if it's in any heap block. Unfortunately this
54 means a linear search through all allocated heap blocks. The
55 assertion says that if it's detected as a heap block, then we
56 must have an allocation context for it, since all heap blocks
57 should have an allocation context. */
58 Bool is_heapblock
59 = HG_(mm_find_containing_block)(
60 &ad->hctxt,
61 &ad->haddr,
62 &ad->hszB,
63 a
64 );
65 tl_assert(is_heapblock == (ad->hctxt != NULL));
66
67 if (!ad->hctxt) {
68 /* It's not in any heap block. See if we can map it to a
69 stack or global symbol. */
70
71 ad->descr1
72 = VG_(newXA)( HG_(zalloc), "hg.addrdescr.descr1",
73 HG_(free), sizeof(HChar) );
74 ad->descr2
75 = VG_(newXA)( HG_(zalloc), "hg.addrdescr.descr2",
76 HG_(free), sizeof(HChar) );
77
78 (void) VG_(get_data_description)( ad->descr1,
79 ad->descr2,
80 a );
81
82 /* If there's nothing in descr1/2, free it. Why is it safe to
83 to VG_(indexXA) at zero here? Because
84 VG_(get_data_description) guarantees to zero terminate
85 descr1/2 regardless of the outcome of the call. So there's
86 always at least one element in each XA after the call.
87 */
88 if (0 == VG_(strlen)( VG_(indexXA)(ad->descr1, 0 ))) {
89 VG_(deleteXA)( ad->descr1 );
90 ad->descr1 = NULL;
91 }
92 if (0 == VG_(strlen)( VG_(indexXA)( ad->descr2, 0 ))) {
93 VG_(deleteXA)( ad->descr2 );
94 ad->descr2 = NULL;
95 }
96 }
97}
98
99void HG_(pp_addrdescr) (Bool xml, const HChar* what, Addr addr,
100 AddrDescr* ad,
101 void(*print)(const HChar *format, ...))
102{
103 /* If we have a description of the address in terms of a heap
104 block, show it. */
105 if (ad->hctxt) {
106 SizeT delta = addr - ad->haddr;
107 if (xml) {
108 (*print)(" <auxwhat>%s %p is %ld bytes inside a block "
109 "of size %ld alloc'd</auxwhat>\n", what,
110 (void*)addr, delta,
111 ad->hszB);
112 VG_(pp_ExeContext)( ad->hctxt );
113 } else {
114 (*print)("\n");
115 (*print)("%s %p is %ld bytes inside a block "
116 "of size %ld alloc'd\n", what,
117 (void*)addr, delta,
118 ad->hszB);
119 VG_(pp_ExeContext)( ad->hctxt );
120 }
121 }
122
123 /* If we have a better description of the address, show it.
124 Note that in XML mode, it will already by nicely wrapped up
125 in tags, either <auxwhat> or <xauxwhat>, so we can just emit
126 it verbatim. */
127 if (xml) {
128 if (ad->descr1)
129 (*print)( " %s\n",
130 (HChar*)VG_(indexXA)( ad->descr1, 0 ) );
131 if (ad->descr2)
132 (*print)( " %s\n",
133 (HChar*)VG_(indexXA)( ad->descr2, 0 ) );
134 } else {
135 if (ad->descr1 || ad->descr2)
136 (*print)("\n");
137 if (ad->descr1)
138 (*print)( "%s\n",
139 (HChar*)VG_(indexXA)( ad->descr1, 0 ) );
140 if (ad->descr2)
141 (*print)( "%s\n",
142 (HChar*)VG_(indexXA)( ad->descr2, 0 ) );
143 }
144}
145
146static void void_printf(const HChar *format, ...)
147{
148 UInt ret;
149 va_list vargs;
150 va_start(vargs, format);
151 ret = VG_(vprintf)(format, vargs);
152 va_end(vargs);
153}
154
155Bool HG_(get_and_pp_addrdescr) (const HChar* what, Addr addr)
156{
157
158 Bool ret;
159 AddrDescr glad;
160
161 HG_(init_AddrDescr) (&glad);
162
163 HG_(describe_addr) (addr, &glad);
164
165 HG_(pp_addrdescr) (False /* xml */, what, addr,
166 &glad,
167 void_printf);
168 ret = glad.hctxt || glad.descr1 || glad.descr2;
169
170 HG_(clear_addrdesc) (&glad);
171
172 return ret;
173}
174
175void HG_(clear_addrdesc) ( AddrDescr* ad)
176{
177 ad->hctxt = NULL;
178 ad->haddr = 0;
179 ad->hszB = 0;
180 if (ad->descr1 != NULL) {
181 VG_(deleteXA)( ad->descr1 );
182 ad->descr1 = NULL;
183 }
184 if (ad->descr2 != NULL) {
185 VG_(deleteXA)( ad->descr2 );
186 ad->descr2 = NULL;
187 }
188}
189
190/*--------------------------------------------------------------------*/
191/*--- end hg_addrdescr.c ---*/
192/*--------------------------------------------------------------------*/