1
2/*--------------------------------------------------------------------*/
3/*--- Obtaining information about an address.  pub_tool_addrinfo.h ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2015 Julian Seward
11      jseward@acm.org
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31#ifndef __PUB_TOOL_ADDRINFO_H
32#define __PUB_TOOL_ADDRINFO_H
33
34#include "pub_tool_basics.h"   // VG_ macro
35#include "pub_tool_aspacemgr.h"  // SegKind
36
37/*====================================================================*/
38/*=== Obtaining information about an address                       ===*/
39/*====================================================================*/
40
41// Different kinds of blocks.
42// Block_Mallocd is used by tools that maintain detailed information about
43//   Client allocated heap blocks.
44// Block_Freed is used by tools such as memcheck that maintain a 'quarantine'
45//   list of blocks freed by the Client but not yet physically freed.
46// Block_MempoolChunk and Block_UserG are used for mempool or user defined heap
47//   blocks.
48// Block_ClientArenaMallocd and Block_ClientArenaFree are used when the tool
49//   replaces the malloc/free/... functions but does not maintain detailed
50//   information about Client allocated heap blocks.
51// Block_ValgrindArenaMallocd and Block_ValgrindArenaFree are used for heap
52//   blocks of Valgrind internal heap.
53typedef enum {
54   Block_Mallocd = 111,
55   Block_Freed,
56   Block_MempoolChunk,
57   Block_UserG,
58   Block_ClientArenaMallocd,
59   Block_ClientArenaFree,
60   Block_ValgrindArenaMallocd,
61   Block_ValgrindArenaFree,
62} BlockKind;
63
64/* ------------------ Addresses -------------------- */
65
66/* The classification of a faulting address. */
67typedef
68   enum {
69      Addr_Undescribed, // as-yet unclassified
70      Addr_Unknown,     // classification yielded nothing useful
71      Addr_Block,       // in malloc'd/free'd block
72      Addr_Stack,       // on a thread's stack
73      Addr_DataSym,     // in a global data sym
74      Addr_Variable,    // variable described by the debug info
75      Addr_SectKind,    // Section from a mmap-ed object file
76      Addr_BrkSegment,  // address in brk data segment
77      Addr_SegmentKind  // Client segment (mapped memory)
78   }
79   AddrTag;
80
81/* For an address in a stack, gives the address position in this stack. */
82typedef
83   enum {
84      StackPos_stacked,         // Addressable and 'active' stack zone.
85      StackPos_below_stack_ptr, // Below stack ptr
86      StackPos_guard_page       // In the guard page
87   }
88   StackPos;
89
90
91/* Note about ThreadInfo tid and tnr in various parts of _Addrinfo:
92   A tid is an index in the VG_(threads)[] array. The entries
93   in  VG_(threads) array are re-used, so the tid in an 'old' _Addrinfo
94   might be misleading: if the thread that was using tid has been terminated
95   and the tid was re-used by another thread, the tid will very probably
96   be wrongly interpreted by the user.
97   So, such an _Addrinfo should be printed just after it has been produced,
98   before the tid could possibly be re-used by another thread.
99
100   A tool such as helgrind is uniquely/unambiguously identifying each thread
101   by a number. If the tool sets tnr between the call to
102   VG_(describe_addr) and the call to VG_(pp_addrinfo), then VG_(pp_addrinfo)
103   will by preference print tnr instead of tid.
104   Visually, a tid will be printed as   thread %d
105   while a tnr will be printed as       thread #%d
106*/
107
108typedef
109   struct _ThreadInfo {
110      ThreadId tid;   // 0 means thread not known.
111      UInt     tnr;   // 0 means no tool specific thread nr, or not known.
112   } ThreadInfo;
113
114/* Zeroes/clear all the fields of *tinfo. */
115extern void VG_(initThreadInfo) (ThreadInfo *tinfo);
116
117typedef
118   struct _AddrInfo
119   AddrInfo;
120
121struct _AddrInfo {
122   AddrTag tag;
123   union {
124      // As-yet unclassified.
125      struct { } Undescribed;
126
127      // On a stack. tinfo indicates which thread's stack?
128      // IP is the address of an instruction of the function where the
129      // stack address was. 0 if not found.
130      // frameNo is the frame nr of the call where the stack address was.
131      // -1 if not found.
132      // stackPos describes the address 'position' in the stack.
133      // If stackPos is StackPos_below_stack_ptr or StackPos_guard_page,
134      // spoffset gives the offset from the thread stack pointer.
135      // (spoffset will be negative, as stacks are assumed growing down).
136      struct {
137         ThreadInfo tinfo;
138         Addr     IP;
139         Int      frameNo;
140         StackPos stackPos;
141         PtrdiffT spoffset;
142      } Stack;
143
144      // This covers heap blocks (normal and from mempools), user-defined
145      // blocks and Arena blocks.
146      // alloc_tinfo identifies the thread that has allocated the block.
147      // This is used by tools such as helgrind that maintain
148      // more detailed informations about client blocks.
149      struct {
150         BlockKind   block_kind;
151         const HChar* block_desc;   // "block","mempool","user-defined",arena
152         SizeT       block_szB;
153         PtrdiffT    rwoffset;
154         ExeContext* allocated_at;  // might be null_ExeContext.
155         ThreadInfo  alloc_tinfo;   // which thread did alloc this block.
156         ExeContext* freed_at;      // might be null_ExeContext.
157      } Block;
158
159      // In a global .data symbol.  This holds
160      // the variable's name (zero terminated), plus a (memory) offset.
161      struct {
162         HChar   *name;
163         PtrdiffT offset;
164      } DataSym;
165
166      // Is described by Dwarf debug info.  XArray*s of HChar.
167      struct {
168         XArray* /* of HChar */ descr1;
169         XArray* /* of HChar */ descr2;
170      } Variable;
171
172      // Could only narrow it down to be the PLT/GOT/etc of a given
173      // object.  Better than nothing, perhaps.
174      struct {
175         HChar      *objname;
176         VgSectKind kind;
177      } SectKind;
178
179      // Described address is or was in the brk data segment.
180      // brk_limit is the limit that was in force
181      // at the time address was described.
182      // If address is >= brk_limit, it means address is in a zone
183      // of the data segment that was shrinked.
184      struct {
185         Addr brk_limit; // limit in force when address was described.
186      } BrkSegment;
187
188      struct {
189         SegKind segkind;   // SkAnonC, SkFileC or SkShmC.
190         HChar   *filename; // NULL if segkind != SkFileC
191         Bool    hasR;
192         Bool    hasW;
193         Bool    hasX;
194      } SegmentKind;
195
196      // Classification yielded nothing useful.
197      struct { } Unknown;
198
199   } Addr;
200};
201
202
203/* Describe an address as best you can, putting the result in ai.
204   On entry, ai->tag must be equal to Addr_Undescribed.
205   This might allocate some memory, that can be cleared with
206   VG_(clear_addrinfo). */
207extern void VG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai );
208
209extern void VG_(clear_addrinfo) ( AddrInfo* ai);
210
211/* Prints the AddrInfo ai describing a.
212   Note that an ai with tag Addr_Undescribed will cause an assert.*/
213extern void VG_(pp_addrinfo) ( Addr a, const AddrInfo* ai );
214
215/* Same as VG_(pp_addrinfo) but provides some memcheck specific behaviour:
216   * maybe_gcc indicates Addr a was just below the stack ptr when the error
217     with a was encountered.
218   * the message for Unknown tag is slightly different, as memcheck
219     has a recently freed list. */
220extern void VG_(pp_addrinfo_mc) ( Addr a, const AddrInfo* ai, Bool maybe_gcc );
221
222#endif   // __PUB_TOOL_ADDRINFO_H
223
224/*--------------------------------------------------------------------*/
225/*--- end                                                          ---*/
226/*--------------------------------------------------------------------*/
227