
/*--------------------------------------------------------------------*/
/*--- Obtaining information about an address.  pub_tool_addrinfo.h ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2000-2013 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

/*====================================================================*/
/*=== 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_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 informations 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;

      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                                                          ---*/
/*--------------------------------------------------------------------*/
