pub_tool_tooliface.h revision 436e89c602e787e7a27dd6624b09beed41a0da8a
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- The core/tool interface. pub_tool_tooliface.h ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2000-2013 Julian Seward 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown jseward@acm.org 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef __PUB_TOOL_TOOLIFACE_H 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __PUB_TOOL_TOOLIFACE_H 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_errormgr.h" // for Error, Supp 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex.h" // for all Vex stuff 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The interface version */ 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialise tool. Must do the following: 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - initialise the `details' struct, via the VG_(details_*)() functions 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - register the basic tool functions, via VG_(basic_tool_funcs)(). 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown May do the following: 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - initialise the `needs' struct to indicate certain requirements, via 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the VG_(needs_*)() functions 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - any other tool-specific initialisation 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void (*VG_(tl_pre_clo_init)) ( void ); 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Every tool must include this macro somewhere, exactly once. The 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown interface version is no longer relevant, but we kept the same name 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to avoid requiring changes to tools. 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VG_DETERMINE_INTERFACE_VERSION(pre_clo_init) \ 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*VG_(tl_pre_clo_init)) ( void ) = pre_clo_init; 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Basic tool functions */ 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The tool_instrument function is passed as a callback to 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LibVEX_Translate. VgCallbackClosure carries additional info 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which the instrumenter might like to know, but which is opaque to 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vex. 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr64 nraddr; /* non-redirected guest address */ 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr64 readdr; /* redirected guest address */ 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadId tid; /* tid requesting translation */ 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VgCallbackClosure; 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(basic_tool_funcs)( 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Do any initialisation that can only be done after command line 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // processing. 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*post_clo_init)(void), 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Instrument a basic block. Must be a true function, ie. the same 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // input always results in the same output, because basic blocks 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // can be retranslated, unless you're doing something really 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // strange. Anyway, the arguments. Mostly they are straightforward 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // except for the distinction between redirected and non-redirected 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // guest code addresses, which is important to understand. 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VgCallBackClosure* closure contains extra arguments passed 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // from Valgrind to the instrumenter, which Vex doesn't know about. 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // You are free to look inside this structure. 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // * closure->tid is the ThreadId of the thread requesting the 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // translation. Not sure why this is here; perhaps callgrind 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // uses it. 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // * closure->nraddr is the non-redirected guest address of the 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // start of the translation. In other words, the translation is 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // being constructed because the guest program jumped to 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // closure->nraddr but no translation of it was found. 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // * closure->readdr is the redirected guest address, from which 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the translation was really made. 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // To clarify this, consider what happens when, in Memcheck, the 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // first call to malloc() happens. The guest program will be 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // trying to jump to malloc() in libc; hence ->nraddr will contain 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // that address. However, Memcheck intercepts and replaces 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // malloc, hence ->readdr will be the address of Memcheck's 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // malloc replacement in 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // coregrind/m_replacemalloc/vg_replacemalloc.c. It follows 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // that the first IMark in the translation will be labelled as 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // from ->readdr rather than ->nraddr. 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Since most functions are not redirected, the majority of the 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // time ->nraddr will be the same as ->readdr. However, you 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // cannot assume this: if your tool has metadata associated 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // with code addresses it will get into deep trouble if it does 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // make this assumption. 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // IRSB* sb_in is the incoming superblock to be instrumented, 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // in flat IR form. 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VexGuestLayout* layout contains limited info on the layout of 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the guest state: where the stack pointer and program counter 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // are, and which fields should be regarded as 'always defined'. 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Memcheck uses this. 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VexGuestExtents* vge points to a structure which states the 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // precise byte ranges of original code from which this translation 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // was made (there may be up to three different ranges involved). 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Note again that these are the real addresses from which the code 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // came. And so it should be the case that closure->readdr is the 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // same as vge->base[0]; indeed Cachegrind contains this assertion. 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Tools which associate shadow data with code addresses 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // (cachegrind, callgrind) need to be particularly clear about 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // whether they are making the association with redirected or 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // non-redirected code addresses. Both approaches are viable 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // but you do need to understand what's going on. See comments 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // below on discard_basic_block_info(). 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // IRType gWordTy and IRType hWordTy contain the types of native 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // words on the guest (simulated) and host (real) CPUs. They will 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // by either Ity_I32 or Ity_I64. So far we have never built a 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // cross-architecture Valgrind so they should always be the same. 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- Further comments about the IR that your --- */ 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- instrumentation function will receive. --- */ 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In the incoming IRSB, the IR for each instruction begins with an 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt_IMark, which states the address and length of the 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instruction from which this IR came. This makes it easy for 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown profiling-style tools to know precisely which guest code 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addresses are being executed. 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown However, before the first IRStmt_IMark, there may be other IR 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown statements -- a preamble. In most cases this preamble is empty, 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown but when it isn't, what it contains is some supporting IR that 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the JIT uses to ensure control flow works correctly. This 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown preamble does not modify any architecturally defined guest state 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (registers or memory) and so does not contain anything that will 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be of interest to your tool. 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should therefore 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (1) copy any IR preceding the first IMark verbatim to the start 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of the output IRSB. 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (2) not try to instrument it or modify it in any way. 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For the record, stuff that may be in the preamble at 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown present is: 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - A self-modifying-code check has been requested for this block. 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The preamble will contain instructions to checksum the block, 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown compare against the expected value, and exit the dispatcher 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown requesting a discard (hence forcing a retranslation) if they 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown don't match. 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - This block is known to be the entry point of a wrapper of some 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function F. In this case the preamble contains code to write 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the address of the original F (the fn being wrapped) into a 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'hidden' guest state register _NRADDR. The wrapper can later 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown read this register using a client request and make a 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown non-redirected call to it using another client-request-like 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown magic macro. 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - For platforms that use the AIX ABI (including ppc64-linux), it 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is necessary to have a preamble even for replacement functions 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (not just for wrappers), because it is necessary to switch the 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown R2 register (constant-pool pointer) to a different value when 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown swizzling the program counter. 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Hence the preamble pushes both R2 and LR (the return address) 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown on a small 16-entry stack in the guest state and sets R2 to an 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown appropriate value for the wrapper/replacement fn. LR is then 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set so that the wrapper/replacement fn returns to a magic IR 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stub which restores R2 and LR and returns. 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It's all hugely ugly and fragile. And it places a stringent 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown requirement on m_debuginfo to find out the correct R2 (toc 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pointer) value for the wrapper/replacement function. So much 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown so that m_redir will refuse to honour a redirect-to-me request 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if it cannot find (by asking m_debuginfo) a plausible R2 value 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for 'me'. 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Because this mechanism maintains a shadow stack of (R2,LR) 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pairs in the guest state, it will fail if the 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wrapper/redirection function, or anything it calls, longjumps 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out past the wrapper, because then the magic return stub will 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not be run and so the shadow stack will not be popped. So it 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown will quickly fill up. Fortunately none of this applies to 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown {x86,amd64,ppc32}-linux; on those platforms, wrappers can 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown longjump and recurse arbitrarily and everything should work 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fine. 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note that copying the preamble verbatim may cause complications 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for your instrumenter if you shadow IR temporaries. See big 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown comment in MC_(instrument) in memcheck/mc_translate.c for 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown details. 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB*(*instrument)(VgCallbackClosure* closure, 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* sb_in, 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VexGuestLayout* layout, 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VexGuestExtents* vge, 223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexArchInfo* archinfo_host, 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType gWordTy, 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType hWordTy), 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Finish up, print out any results, etc. `exitcode' is program's exit 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // code. The shadow can be found with VG_(get_exit_status_shadow)(). 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*fini)(Int) 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Details */ 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Default value for avg_translations_sizeB (in bytes), indicating typical 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown code expansion of about 6:1. */ 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VG_DEFAULT_TRANS_SIZEB 172 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Information used in the startup message. `name' also determines the 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown string used for identifying suppressions in a suppression file as 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown belonging to this tool. `version' can be NULL, in which case (not 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown surprisingly) no version info is printed; this mechanism is designed for 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tools distributed with Valgrind that share a version number with 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Valgrind. Other tools not distributed as part of Valgrind should 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown probably have their own version number. */ 246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void VG_(details_name) ( const HChar* name ); 247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void VG_(details_version) ( const HChar* version ); 248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void VG_(details_description) ( const HChar* description ); 249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void VG_(details_copyright_author) ( const HChar* copyright_author ); 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Average size of a translation, in bytes, so that the translation 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown storage machinery can allocate memory appropriately. Not critical, 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setting is optional. */ 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(details_avg_translation_sizeB) ( UInt size ); 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* String printed if an `tl_assert' assertion fails or VG_(tool_panic) 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is called. Should probably be an email address. */ 258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void VG_(details_bug_reports_to) ( const HChar* bug_reports_to ); 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Needs */ 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Should __libc_freeres() be run? Bugs in it can crash the tool. */ 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_libc_freeres) ( void ); 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Want to have errors detected by Valgrind's core reported? Includes: 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - pthread API errors (many; eg. unlocking a non-locked mutex) 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [currently disabled] 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - invalid file descriptors to syscalls like read() and write() 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - bad signal numbers passed to sigaction() 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - attempt to install signal handler for SIGKILL or SIGSTOP */ 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_core_errors) ( void ); 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Booleans that indicate extra operations are defined; if these are True, 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the corresponding template functions (given below) must be defined. A 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lot like being a member of a type class. */ 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Want to report errors from tool? This implies use of suppressions, too. */ 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_tool_errors) ( 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Identify if two errors are equal, or close enough. This function is 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // only called if e1 and e2 will have the same error kind. `res' indicates 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // how close is "close enough". `res' should be passed on as necessary, 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // eg. if the Error's `extra' part contains an ExeContext, `res' should be 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // passed to VG_(eq_ExeContext)() if the ExeContexts are considered. Other 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // than that, probably don't worry about it unless you have lots of very 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // similar errors occurring. 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*eq_Error)(VgRes res, Error* e1, Error* e2), 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // We give tools a chance to have a look at errors 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // just before they are printed. That is, before_pp_Error is 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // called just before pp_Error itself. This gives the tool a 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // chance to look at the just-about-to-be-printed error, so as to 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // emit any arbitrary output if wants to, before the error itself 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // is printed. This functionality was added to allow Helgrind to 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // print thread-announcement messages immediately before the 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // errors that refer to them. 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*before_pp_Error)(Error* err), 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Print error context. 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*pp_Error)(Error* err), 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Should the core indicate which ThreadId each error comes from? 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool show_ThreadIDs_for_errors, 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Should fill in any details that could be postponed until after the 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // decision whether to ignore the error (ie. details not affecting the 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // result of VG_(tdict).tool_eq_Error()). This saves time when errors 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // are ignored. 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Yuk. 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Return value: must be the size of the `extra' part in bytes -- used by 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the core to make a copy. 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt (*update_extra)(Error* err), 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Return value indicates recognition. If recognised, must set skind using 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VG_(set_supp_kind)(). 316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool (*recognised_suppression)(const HChar* name, Supp* su), 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Read any extra info for this suppression kind. Most likely for filling 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // in the `extra' and `string' parts (with VG_(set_supp_{extra, string})()) 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // of a suppression if necessary. Should return False if a syntax error 321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // occurred, True otherwise. 322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // fd, bufpp, nBufp and lineno are the same as for VG_(get_line). 323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool (*read_extra_suppression_info)(Int fd, HChar** bufpp, SizeT* nBufp, 324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int* lineno, Supp* su), 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This should just check the kinds match and maybe some stuff in the 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // `string' and `extra' field if appropriate (using VG_(get_supp_*)() to 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // get the relevant suppression parts). 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*error_matches_suppression)(Error* err, Supp* su), 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This should return the suppression name, for --gen-suppressions, or NULL 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // if that error type cannot be suppressed. This is the inverse of 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VG_(tdict).tool_recognised_suppression(). 334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* (*get_error_name)(Error* err), 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This should print into buf[0..nBuf-1] any extra info for the 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // error, for --gen-suppressions, but not including any leading 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // spaces nor a trailing newline. When called, buf[0 .. nBuf-1] 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // will be zero filled, and it is expected and checked that the 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // last element is still zero after the call. In other words the 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // tool may not overrun the buffer, and this is checked for. If 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // there is any info printed in the buffer, return True, otherwise 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // do nothing, and return False. This function is the inverse of 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VG_(tdict).tool_read_extra_suppression_info(). 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*print_extra_suppression_info)(Error* err, 346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*OUT*/HChar* buf, Int nBuf), 347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // This is similar to print_extra_suppression_info, but is used 349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // to print information such as additional statistical counters 350436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // as part of the used suppression list produced by -v. 351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool (*print_extra_suppression_use)(Supp* su, 352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*OUT*/HChar* buf, Int nBuf), 353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Called by error mgr once it has been established that err 355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // is suppressed by su. update_extra_suppression_use typically 356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // can be used to update suppression extra information such as 357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // some statistical counters that will be printed by 358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // print_extra_suppression_use. 359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void (*update_extra_suppression_use)(Error* err, Supp* su) 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Is information kept by the tool about specific instructions or 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown translations? (Eg. for cachegrind there are cost-centres for every 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instruction, stored in a per-translation fashion.) If so, the info 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown may have to be discarded when translations are unloaded (eg. due to 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .so unloading, or otherwise at the discretion of m_transtab, eg 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown when the table becomes too full) to avoid stale information being 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown reused for new translations. */ 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_superblock_discards) ( 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Discard any information that pertains to specific translations 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // or instructions within the address range given. There are two 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // possible approaches. 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // - If info is being stored at a per-translation level, use orig_addr 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // to identify which translation is being discarded. Each translation 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // will be discarded exactly once. 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This orig_addr will match the closure->nraddr which was passed to 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // to instrument() (see extensive comments above) when this 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // translation was made. Note that orig_addr won't necessarily be 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the same as the first address in "extents". 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // - If info is being stored at a per-instruction level, you can get 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the address range(s) being discarded by stepping through "extents". 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Note that any single instruction may belong to more than one 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // translation, and so could be covered by the "extents" of more than 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // one call to this function. 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Doing it the first way (as eg. Cachegrind does) is probably easier. 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*discard_superblock_info)(Addr64 orig_addr, VexGuestExtents extents) 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Tool defines its own command line options? */ 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_command_line_options) ( 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Return True if option was recognised, False if it wasn't (but also see 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // below). Presumably sets some state to record the option as well. 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Nb: tools can assume that the argv will never disappear. So they can, 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // for example, store a pointer to a string within an option, rather than 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // having to make a copy. 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Options (and combinations of options) should be checked in this function 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // if possible rather than in post_clo_init(), and if they are bad then 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VG_(fmsg_bad_option)() should be called. This ensures that the 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // messaging is consistent with command line option errors from the core. 402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool (*process_cmd_line_option)(const HChar* argv), 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Print out command line usage for options for normal tool operation. 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*print_usage)(void), 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Print out command line usage for options for debugging the tool. 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*print_debug_usage)(void) 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Tool defines its own client requests? */ 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_client_requests) ( 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // If using client requests, the number of the first request should be equal 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // to VG_USERREQ_TOOL_BASE('X', 'Y'), where 'X' and 'Y' form a suitable two 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // character identification for the string. The second and subsequent 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // requests should follow. 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This function should use the VG_IS_TOOL_USERREQ macro (in 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // include/valgrind.h) to first check if it's a request for this tool. Then 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // should handle it if it's recognised (and return True), or return False if 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // not recognised. arg_block[0] holds the request number, any further args 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // from the request are in arg_block[1..]. 'ret' is for the return value... 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // it should probably be filled, if only with 0. 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*handle_client_request)(ThreadId tid, UWord* arg_block, UWord* ret) 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Tool does stuff before and/or after system calls? */ 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Nb: If either of the pre_ functions malloc() something to return, the 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// corresponding post_ function had better free() it! 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Also, the args are the 'original args' -- that is, it may be 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// that the syscall pre-wrapper will modify the args before the 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// syscall happens. So these args are the original, un-modified 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// args. Finally, nArgs merely indicates the length of args[..], 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// it does not indicate how many of those values are actually 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// relevant to the syscall. args[0 .. nArgs-1] is guaranteed 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// to be defined and to contain all the args for this syscall, 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// possibly including some trailing zeroes. 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_syscall_wrapper) ( 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (* pre_syscall)(ThreadId tid, UInt syscallno, 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord* args, UInt nArgs), 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*post_syscall)(ThreadId tid, UInt syscallno, 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord* args, UInt nArgs, SysRes res) 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Are tool-state sanity checks performed? */ 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Can be useful for ensuring a tool's correctness. cheap_sanity_check() 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// is called very frequently; expensive_sanity_check() is called less 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// frequently and can be more involved. 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_sanity_checks) ( 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool(*cheap_sanity_check)(void), 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool(*expensive_sanity_check)(void) 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Can the tool produce stats during execution? */ 455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void VG_(needs_print_stats) ( 456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Print out tool status. Note that the stats at end of execution 457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // should be output by the VG_(basic_tool_funcs) "fini" function. 458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void (*print_stats)(void) 459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov); 460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Do we need to see variable type and location information? */ 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_var_info) ( void ); 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Does the tool replace malloc() and friends with its own versions? 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This has to be combined with the use of a vgpreload_<tool>.so module 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown or it won't work. See massif/Makefile.am for how to build it. */ 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// The 'p' prefix avoids GCC complaints about overshadowing global names. 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_malloc_replacement)( 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*pmalloc) ( ThreadId tid, SizeT n ), 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*p__builtin_new) ( ThreadId tid, SizeT n ), 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*p__builtin_vec_new) ( ThreadId tid, SizeT n ), 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*pmemalign) ( ThreadId tid, SizeT align, SizeT n ), 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*pcalloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ), 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*pfree) ( ThreadId tid, void* p ), 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*p__builtin_delete) ( ThreadId tid, void* p ), 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*p__builtin_vec_delete) ( ThreadId tid, void* p ), 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*prealloc) ( ThreadId tid, void* p, SizeT new_size ), 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT (*pmalloc_usable_size) ( ThreadId tid, void* p), 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT client_malloc_redzone_szB 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Can the tool do XML output? This is a slight misnomer, because the tool 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * is not requesting the core to do anything, rather saying "I can handle 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * it". */ 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_xml_output) ( void ); 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Does the tool want to have one final pass over the IR after tree 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown building but before instruction selection? If so specify the 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function here. */ 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_final_IR_tidy_pass) ( IRSB*(*final_tidy)(IRSB*) ); 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Core events to track */ 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Part of the core from which this call was made. Useful for determining 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown what kind of error message should be emitted. */ 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { Vg_CoreStartup=1, Vg_CoreSignal, Vg_CoreSysCall, 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This is for platforms where syscall args are passed on the 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // stack; although pre_mem_read is the callback that will be 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // called, such an arg should be treated (with respect to 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // presenting information to the user) as if it was passed in a 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // register, ie. like pre_reg_read. 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vg_CoreSysCallArgInMem, 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vg_CoreTranslate, Vg_CoreClientReq 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } CorePart; 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Events happening in core to track. To be notified, pass a callback 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function to the appropriate function. To ignore an event, don't do 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown anything (the default is for events to be ignored). 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note that most events aren't passed a ThreadId. If the event is one called 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown from generated code (eg. new_mem_stack_*), you can use 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_running_tid)() to find it. Otherwise, it has to be passed in, 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as in pre_mem_read, and so the event signature will require changing. 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Memory events (Nb: to track heap allocation/freeing, a tool must replace 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown malloc() et al. See above how to do this.) 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown These ones occur at startup, upon some signals, and upon some syscalls. 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For new_mem_brk and new_mem_stack_signal, the supplied ThreadId 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown indicates the thread for whom the new memory is being allocated. 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For new_mem_startup and new_mem_mmap, the di_handle argument is a 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown handle which can be used to retrieve debug info associated with the 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mapping or allocation (because it is of a file that Valgrind has 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown decided to read debug info from). If the value is zero, there is 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown no associated debug info. If the value exceeds zero, it can be 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown supplied as an argument to selected queries in m_debuginfo. 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_startup) (void(*f)(Addr a, SizeT len, 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool rr, Bool ww, Bool xx, 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong di_handle)); 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_signal)(void(*f)(Addr a, SizeT len, ThreadId tid)); 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_brk) (void(*f)(Addr a, SizeT len, ThreadId tid)); 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_mmap) (void(*f)(Addr a, SizeT len, 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool rr, Bool ww, Bool xx, 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong di_handle)); 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_copy_mem_remap) (void(*f)(Addr from, Addr to, SizeT len)); 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_change_mem_mprotect) (void(*f)(Addr a, SizeT len, 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool rr, Bool ww, Bool xx)); 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_signal)(void(*f)(Addr a, SizeT len)); 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_brk) (void(*f)(Addr a, SizeT len)); 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_munmap) (void(*f)(Addr a, SizeT len)); 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These ones are called when SP changes. A tool could track these itself 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (except for ban_mem_stack) but it's much easier to use the core's help. 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The specialised ones are called in preference to the general one, if they 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are defined. These functions are called a lot if they are used, so 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown specialising can optimise things significantly. If any of the 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown specialised cases are defined, the general case must be defined too. 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Nb: all the specialised ones must use the VG_REGPARM(n) attribute. 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For the _new functions, a tool may specify with with-ECU 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ExeContext Unique) or without-ECU version for each size, but not 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown both. If the with-ECU version is supplied, then the core will 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arrange to pass, as the ecu argument, a 32-bit int which uniquely 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown identifies the instruction moving the stack pointer down. This 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32-bit value is as obtained from VG_(get_ECU_from_ExeContext). 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_ExeContext_from_ECU) can then be used to retrieve the 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown associated depth-1 ExeContext for the location. All this 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown complexity is provided to support origin tracking in Memcheck. 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_4_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_8_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_12_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_16_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_32_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_112_w_ECU)(VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_128_w_ECU)(VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_144_w_ECU)(VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_160_w_ECU)(VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_w_ECU) (void(*f)(Addr a, SizeT len, 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt ecu)); 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_4) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_8) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_12) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_16) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_32) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_112)(VG_REGPARM(1) void(*f)(Addr new_ESP)); 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_128)(VG_REGPARM(1) void(*f)(Addr new_ESP)); 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_144)(VG_REGPARM(1) void(*f)(Addr new_ESP)); 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_160)(VG_REGPARM(1) void(*f)(Addr new_ESP)); 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack) (void(*f)(Addr a, SizeT len)); 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_4) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_8) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_12) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_16) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_32) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_112)(VG_REGPARM(1) void(*f)(Addr die_ESP)); 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_128)(VG_REGPARM(1) void(*f)(Addr die_ESP)); 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_144)(VG_REGPARM(1) void(*f)(Addr die_ESP)); 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_160)(VG_REGPARM(1) void(*f)(Addr die_ESP)); 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack) (void(*f)(Addr a, SizeT len)); 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Used for redzone at end of thread stacks */ 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_ban_mem_stack) (void(*f)(Addr a, SizeT len)); 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These ones occur around syscalls, signal handling, etc */ 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_mem_read) (void(*f)(CorePart part, ThreadId tid, 608436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* s, Addr a, SizeT size)); 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_mem_read_asciiz)(void(*f)(CorePart part, ThreadId tid, 610436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* s, Addr a)); 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_mem_write) (void(*f)(CorePart part, ThreadId tid, 612436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* s, Addr a, SizeT size)); 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_post_mem_write) (void(*f)(CorePart part, ThreadId tid, 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr a, SizeT size)); 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Register events. Use VG_(set_shadow_state_area)() to set the shadow regs 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for these events. */ 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_reg_read) (void(*f)(CorePart part, ThreadId tid, 619436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* s, PtrdiffT guest_state_offset, 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT size)); 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_post_reg_write)(void(*f)(CorePart part, ThreadId tid, 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PtrdiffT guest_state_offset, 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT size)); 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This one is called for malloc() et al if they are replaced by a tool. */ 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_post_reg_write_clientcall_return)( 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void(*f)(ThreadId tid, PtrdiffT guest_state_offset, SizeT size, Addr f)); 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Scheduler events (not exhaustive) */ 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Called when 'tid' starts or stops running client code blocks. 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Gives the total dispatched block count at that event. Note, this 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is not the same as 'tid' holding the BigLock (the lock that ensures 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that only one thread runs at a time): a thread can hold the lock 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for other purposes (making translations, etc) yet not be running 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown client blocks. Obviously though, a thread must hold the lock in 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown order to run client code blocks, so the times bracketed by 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'start_client_code'..'stop_client_code' are a subset of the times 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown when thread 'tid' holds the cpu lock. 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_start_client_code)( 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void(*f)(ThreadId tid, ULong blocks_dispatched) 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_stop_client_code)( 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void(*f)(ThreadId tid, ULong blocks_dispatched) 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Thread events (not exhaustive) 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ll_create: low level thread creation. Called before the new thread 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown has run any instructions (or touched any memory). In fact, called 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown immediately before the new thread has come into existence; the new 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thread can be assumed to exist when notified by this call. 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ll_exit: low level thread exit. Called after the exiting thread 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown has run its last instruction. 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The _ll_ part makes it clear these events are not to do with 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_create or pthread_exit/pthread_join (etc), which are a 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown higher level abstraction synthesised by libpthread. What you can 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be sure of from _ll_create/_ll_exit is the absolute limits of each 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thread's lifetime, and hence be assured that all memory references 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown made by the thread fall inside the _ll_create/_ll_exit pair. This 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is important for tools that need a 100% accurate account of which 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thread is responsible for every memory reference in the process. 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_create/join/exit do not give this property. Calls/returns 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to/from them happen arbitrarily far away from the relevant 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown low-level thread create/quit event. In general a few hundred 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instructions; hence a few hundred(ish) memory references could get 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown misclassified each time. 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pre_thread_first_insn: is called when the thread is all set up and 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ready to go (stack in place, etc) but has not executed its first 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instruction yet. Gives threading tools a chance to ask questions 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown about the thread (eg, what is its initial client stack pointer) 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that are not easily answered at pre_thread_ll_create time. 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For a given thread, the call sequence is: 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ll_create (in the parent's context) 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown first_insn (in the child's context) 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ll_exit (in the child's context) 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_thread_ll_create) (void(*f)(ThreadId tid, ThreadId child)); 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_thread_first_insn)(void(*f)(ThreadId tid)); 688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_thread_ll_exit) (void(*f)(ThreadId tid)); 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Signal events (not exhaustive) 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ... pre_send_signal, post_send_signal ... 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Called before a signal is delivered; `alt_stack' indicates if it is 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delivered on an alternative stack. */ 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_deliver_signal) (void(*f)(ThreadId tid, Int sigNo, 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool alt_stack)); 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Called after a signal is delivered. Nb: unfortunately, if the signal 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown handler longjmps, this won't be called. */ 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_post_deliver_signal)(void(*f)(ThreadId tid, Int sigNo)); 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // __PUB_TOOL_TOOLIFACE_H 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end ---*/ 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 708