/*--------------------------------------------------------------------*/
/*--- Obtaining information about an address. pub_tool_addrinfo.h ---*/
/*--------------------------------------------------------------------*/
/*
This file is part of Valgrind, a dynamic binary instrumentation
framework.
Copyright (C) 2000-2017 Julian Seward
jseward@acm.org
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
The GNU General Public License is contained in the file COPYING.
*/
#ifndef __PUB_TOOL_ADDRINFO_H
#define __PUB_TOOL_ADDRINFO_H
#include "pub_tool_basics.h" // VG_ macro
#include "pub_tool_aspacemgr.h" // SegKind
/*====================================================================*/
/*=== Obtaining information about an address ===*/
/*====================================================================*/
// Different kinds of blocks.
// Block_Mallocd is used by tools that maintain detailed information about
// Client allocated heap blocks.
// Block_Freed is used by tools such as memcheck that maintain a 'quarantine'
// list of blocks freed by the Client but not yet physically freed.
// Block_MempoolChunk and Block_UserG are used for mempool or user defined heap
// blocks.
// Block_ClientArenaMallocd and Block_ClientArenaFree are used when the tool
// replaces the malloc/free/... functions but does not maintain detailed
// information about Client allocated heap blocks.
// Block_ValgrindArenaMallocd and Block_ValgrindArenaFree are used for heap
// blocks of Valgrind internal heap.
typedef enum {
Block_Mallocd = 111,
Block_Freed,
Block_MempoolChunk,
Block_UserG,
Block_ClientArenaMallocd,
Block_ClientArenaFree,
Block_ValgrindArenaMallocd,
Block_ValgrindArenaFree,
} BlockKind;
/* ------------------ Addresses -------------------- */
/* The classification of a faulting address. */
typedef
enum {
Addr_Undescribed, // as-yet unclassified
Addr_Unknown, // classification yielded nothing useful
Addr_Block, // in malloc'd/free'd block
Addr_Stack, // on a thread's stack
Addr_DataSym, // in a global data sym
Addr_Variable, // variable described by the debug info
Addr_SectKind, // Section from a mmap-ed object file
Addr_BrkSegment, // address in brk data segment
Addr_SegmentKind // Client segment (mapped memory)
}
AddrTag;
/* For an address in a stack, gives the address position in this stack. */
typedef
enum {
StackPos_stacked, // Addressable and 'active' stack zone.
StackPos_below_stack_ptr, // Below stack ptr
StackPos_guard_page // In the guard page
}
StackPos;
/* Note about ThreadInfo tid and tnr in various parts of _Addrinfo:
A tid is an index in the VG_(threads)[] array. The entries
in VG_(threads) array are re-used, so the tid in an 'old' _Addrinfo
might be misleading: if the thread that was using tid has been terminated
and the tid was re-used by another thread, the tid will very probably
be wrongly interpreted by the user.
So, such an _Addrinfo should be printed just after it has been produced,
before the tid could possibly be re-used by another thread.
A tool such as helgrind is uniquely/unambiguously identifying each thread
by a number. If the tool sets tnr between the call to
VG_(describe_addr) and the call to VG_(pp_addrinfo), then VG_(pp_addrinfo)
will by preference print tnr instead of tid.
Visually, a tid will be printed as thread %d
while a tnr will be printed as thread #%d
*/
typedef
struct _ThreadInfo {
ThreadId tid; // 0 means thread not known.
UInt tnr; // 0 means no tool specific thread nr, or not known.
} ThreadInfo;
/* Zeroes/clear all the fields of *tinfo. */
extern void VG_(initThreadInfo) (ThreadInfo *tinfo);
typedef
struct _AddrInfo
AddrInfo;
struct _AddrInfo {
AddrTag tag;
union {
// As-yet unclassified.
struct { } Undescribed;
// On a stack. tinfo indicates which thread's stack?
// IP is the address of an instruction of the function where the
// stack address was. 0 if not found.
// frameNo is the frame nr of the call where the stack address was.
// -1 if not found.
// stackPos describes the address 'position' in the stack.
// If stackPos is StackPos_below_stack_ptr or StackPos_guard_page,
// spoffset gives the offset from the thread stack pointer.
// (spoffset will be negative, as stacks are assumed growing down).
struct {
ThreadInfo tinfo;
Addr IP;
Int frameNo;
StackPos stackPos;
PtrdiffT spoffset;
} Stack;
// This covers heap blocks (normal and from mempools), user-defined
// blocks and Arena blocks.
// alloc_tinfo identifies the thread that has allocated the block.
// This is used by tools such as helgrind that maintain
// more detailed information about client blocks.
struct {
BlockKind block_kind;
const HChar* block_desc; // "block","mempool","user-defined",arena
SizeT block_szB;
PtrdiffT rwoffset;
ExeContext* allocated_at; // might be null_ExeContext.
ThreadInfo alloc_tinfo; // which thread did alloc this block.
ExeContext* freed_at; // might be null_ExeContext.
} Block;
// In a global .data symbol. This holds
// the variable's name (zero terminated), plus a (memory) offset.
struct {
HChar *name;
PtrdiffT offset;
} DataSym;
// Is described by Dwarf debug info. XArray*s of HChar.
struct {
XArray* /* of HChar */ descr1;
XArray* /* of HChar */ descr2;
} Variable;
// Could only narrow it down to be the PLT/GOT/etc of a given
// object. Better than nothing, perhaps.
struct {
HChar *objname;
VgSectKind kind;
} SectKind;
// Described address is or was in the brk data segment.
// brk_limit is the limit that was in force
// at the time address was described.
// If address is >= brk_limit, it means address is in a zone
// of the data segment that was shrinked.
struct {
Addr brk_limit; // limit in force when address was described.
} BrkSegment;
struct {
SegKind segkind; // SkAnonC, SkFileC or SkShmC.
HChar *filename; // NULL if segkind != SkFileC
Bool hasR;
Bool hasW;
Bool hasX;
} SegmentKind;
// Classification yielded nothing useful.
struct { } Unknown;
} Addr;
};
/* Describe an address as best you can, putting the result in ai.
On entry, ai->tag must be equal to Addr_Undescribed.
This might allocate some memory, that can be cleared with
VG_(clear_addrinfo). */
extern void VG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai );
extern void VG_(clear_addrinfo) ( AddrInfo* ai);
/* Prints the AddrInfo ai describing a.
Note that an ai with tag Addr_Undescribed will cause an assert.*/
extern void VG_(pp_addrinfo) ( Addr a, const AddrInfo* ai );
/* Same as VG_(pp_addrinfo) but provides some memcheck specific behaviour:
* maybe_gcc indicates Addr a was just below the stack ptr when the error
with a was encountered.
* the message for Unknown tag is slightly different, as memcheck
has a recently freed list. */
extern void VG_(pp_addrinfo_mc) ( Addr a, const AddrInfo* ai, Bool maybe_gcc );
#endif // __PUB_TOOL_ADDRINFO_H
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/