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 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Copyright (C) 2000-2011 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, 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType gWordTy, 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType hWordTy), 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Finish up, print out any results, etc. `exitcode' is program's exit 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // code. The shadow can be found with VG_(get_exit_status_shadow)(). 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*fini)(Int) 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Details */ 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Default value for avg_translations_sizeB (in bytes), indicating typical 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown code expansion of about 6:1. */ 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VG_DEFAULT_TRANS_SIZEB 172 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Information used in the startup message. `name' also determines the 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown string used for identifying suppressions in a suppression file as 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown belonging to this tool. `version' can be NULL, in which case (not 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown surprisingly) no version info is printed; this mechanism is designed for 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tools distributed with Valgrind that share a version number with 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Valgrind. Other tools not distributed as part of Valgrind should 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown probably have their own version number. */ 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(details_name) ( Char* name ); 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(details_version) ( Char* version ); 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(details_description) ( Char* description ); 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(details_copyright_author) ( Char* copyright_author ); 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Average size of a translation, in bytes, so that the translation 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown storage machinery can allocate memory appropriately. Not critical, 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setting is optional. */ 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(details_avg_translation_sizeB) ( UInt size ); 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* String printed if an `tl_assert' assertion fails or VG_(tool_panic) 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is called. Should probably be an email address. */ 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(details_bug_reports_to) ( Char* bug_reports_to ); 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Needs */ 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Should __libc_freeres() be run? Bugs in it can crash the tool. */ 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_libc_freeres) ( void ); 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Want to have errors detected by Valgrind's core reported? Includes: 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - pthread API errors (many; eg. unlocking a non-locked mutex) 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [currently disabled] 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - invalid file descriptors to syscalls like read() and write() 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - bad signal numbers passed to sigaction() 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - attempt to install signal handler for SIGKILL or SIGSTOP */ 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_core_errors) ( void ); 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Booleans that indicate extra operations are defined; if these are True, 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the corresponding template functions (given below) must be defined. A 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lot like being a member of a type class. */ 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Want to report errors from tool? This implies use of suppressions, too. */ 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_tool_errors) ( 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Identify if two errors are equal, or close enough. This function is 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // only called if e1 and e2 will have the same error kind. `res' indicates 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // how close is "close enough". `res' should be passed on as necessary, 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // eg. if the Error's `extra' part contains an ExeContext, `res' should be 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // passed to VG_(eq_ExeContext)() if the ExeContexts are considered. Other 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // than that, probably don't worry about it unless you have lots of very 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // similar errors occurring. 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*eq_Error)(VgRes res, Error* e1, Error* e2), 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // We give tools a chance to have a look at errors 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // just before they are printed. That is, before_pp_Error is 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // called just before pp_Error itself. This gives the tool a 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // chance to look at the just-about-to-be-printed error, so as to 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // emit any arbitrary output if wants to, before the error itself 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // is printed. This functionality was added to allow Helgrind to 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // print thread-announcement messages immediately before the 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // errors that refer to them. 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*before_pp_Error)(Error* err), 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Print error context. 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*pp_Error)(Error* err), 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Should the core indicate which ThreadId each error comes from? 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool show_ThreadIDs_for_errors, 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Should fill in any details that could be postponed until after the 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // decision whether to ignore the error (ie. details not affecting the 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // result of VG_(tdict).tool_eq_Error()). This saves time when errors 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // are ignored. 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Yuk. 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Return value: must be the size of the `extra' part in bytes -- used by 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the core to make a copy. 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt (*update_extra)(Error* err), 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Return value indicates recognition. If recognised, must set skind using 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VG_(set_supp_kind)(). 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*recognised_suppression)(Char* name, Supp* su), 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Read any extra info for this suppression kind. Most likely for filling 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // in the `extra' and `string' parts (with VG_(set_supp_{extra, string})()) 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // of a suppression if necessary. Should return False if a syntax error 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // occurred, True otherwise. bufpp and nBufp are the same as for 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VG_(get_line). 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*read_extra_suppression_info)(Int fd, Char** bufpp, SizeT* nBufp, 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Supp* su), 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This should just check the kinds match and maybe some stuff in the 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // `string' and `extra' field if appropriate (using VG_(get_supp_*)() to 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // get the relevant suppression parts). 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*error_matches_suppression)(Error* err, Supp* su), 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This should return the suppression name, for --gen-suppressions, or NULL 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // if that error type cannot be suppressed. This is the inverse of 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VG_(tdict).tool_recognised_suppression(). 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* (*get_error_name)(Error* err), 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This should print into buf[0..nBuf-1] any extra info for the 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // error, for --gen-suppressions, but not including any leading 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // spaces nor a trailing newline. When called, buf[0 .. nBuf-1] 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // will be zero filled, and it is expected and checked that the 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // last element is still zero after the call. In other words the 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // tool may not overrun the buffer, and this is checked for. If 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // there is any info printed in the buffer, return True, otherwise 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // do nothing, and return False. This function is the inverse of 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VG_(tdict).tool_read_extra_suppression_info(). 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*print_extra_suppression_info)(Error* err, 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/Char* buf, Int nBuf) 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Is information kept by the tool about specific instructions or 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown translations? (Eg. for cachegrind there are cost-centres for every 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instruction, stored in a per-translation fashion.) If so, the info 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown may have to be discarded when translations are unloaded (eg. due to 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .so unloading, or otherwise at the discretion of m_transtab, eg 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown when the table becomes too full) to avoid stale information being 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown reused for new translations. */ 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_superblock_discards) ( 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Discard any information that pertains to specific translations 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // or instructions within the address range given. There are two 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // possible approaches. 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // - If info is being stored at a per-translation level, use orig_addr 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // to identify which translation is being discarded. Each translation 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // will be discarded exactly once. 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This orig_addr will match the closure->nraddr which was passed to 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // to instrument() (see extensive comments above) when this 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // translation was made. Note that orig_addr won't necessarily be 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the same as the first address in "extents". 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // - If info is being stored at a per-instruction level, you can get 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the address range(s) being discarded by stepping through "extents". 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Note that any single instruction may belong to more than one 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // translation, and so could be covered by the "extents" of more than 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // one call to this function. 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Doing it the first way (as eg. Cachegrind does) is probably easier. 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*discard_superblock_info)(Addr64 orig_addr, VexGuestExtents extents) 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Tool defines its own command line options? */ 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_command_line_options) ( 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Return True if option was recognised, False if it wasn't (but also see 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // below). Presumably sets some state to record the option as well. 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Nb: tools can assume that the argv will never disappear. So they can, 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // for example, store a pointer to a string within an option, rather than 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // having to make a copy. 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Options (and combinations of options) should be checked in this function 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // if possible rather than in post_clo_init(), and if they are bad then 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // VG_(fmsg_bad_option)() should be called. This ensures that the 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // messaging is consistent with command line option errors from the core. 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*process_cmd_line_option)(Char* argv), 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Print out command line usage for options for normal tool operation. 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*print_usage)(void), 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Print out command line usage for options for debugging the tool. 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*print_debug_usage)(void) 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Tool defines its own client requests? */ 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_client_requests) ( 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // If using client requests, the number of the first request should be equal 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // to VG_USERREQ_TOOL_BASE('X', 'Y'), where 'X' and 'Y' form a suitable two 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // character identification for the string. The second and subsequent 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // requests should follow. 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This function should use the VG_IS_TOOL_USERREQ macro (in 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // include/valgrind.h) to first check if it's a request for this tool. Then 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // should handle it if it's recognised (and return True), or return False if 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // not recognised. arg_block[0] holds the request number, any further args 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // from the request are in arg_block[1..]. 'ret' is for the return value... 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // it should probably be filled, if only with 0. 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*handle_client_request)(ThreadId tid, UWord* arg_block, UWord* ret) 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Tool does stuff before and/or after system calls? */ 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Nb: If either of the pre_ functions malloc() something to return, the 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// corresponding post_ function had better free() it! 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Also, the args are the 'original args' -- that is, it may be 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// that the syscall pre-wrapper will modify the args before the 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// syscall happens. So these args are the original, un-modified 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// args. Finally, nArgs merely indicates the length of args[..], 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// it does not indicate how many of those values are actually 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// relevant to the syscall. args[0 .. nArgs-1] is guaranteed 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// to be defined and to contain all the args for this syscall, 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// possibly including some trailing zeroes. 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_syscall_wrapper) ( 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (* pre_syscall)(ThreadId tid, UInt syscallno, 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord* args, UInt nArgs), 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*post_syscall)(ThreadId tid, UInt syscallno, 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord* args, UInt nArgs, SysRes res) 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Are tool-state sanity checks performed? */ 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Can be useful for ensuring a tool's correctness. cheap_sanity_check() 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// is called very frequently; expensive_sanity_check() is called less 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// frequently and can be more involved. 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_sanity_checks) ( 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool(*cheap_sanity_check)(void), 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool(*expensive_sanity_check)(void) 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Do we need to see variable type and location information? */ 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_var_info) ( void ); 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Does the tool replace malloc() and friends with its own versions? 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This has to be combined with the use of a vgpreload_<tool>.so module 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown or it won't work. See massif/Makefile.am for how to build it. */ 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// The 'p' prefix avoids GCC complaints about overshadowing global names. 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_malloc_replacement)( 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*pmalloc) ( ThreadId tid, SizeT n ), 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*p__builtin_new) ( ThreadId tid, SizeT n ), 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*p__builtin_vec_new) ( ThreadId tid, SizeT n ), 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*pmemalign) ( ThreadId tid, SizeT align, SizeT n ), 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*pcalloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ), 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*pfree) ( ThreadId tid, void* p ), 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*p__builtin_delete) ( ThreadId tid, void* p ), 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*p__builtin_vec_delete) ( ThreadId tid, void* p ), 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void* (*prealloc) ( ThreadId tid, void* p, SizeT new_size ), 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT (*pmalloc_usable_size) ( ThreadId tid, void* p), 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT client_malloc_redzone_szB 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Can the tool do XML output? This is a slight misnomer, because the tool 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * is not requesting the core to do anything, rather saying "I can handle 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * it". */ 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_xml_output) ( void ); 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Does the tool want to have one final pass over the IR after tree 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown building but before instruction selection? If so specify the 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function here. */ 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void VG_(needs_final_IR_tidy_pass) ( IRSB*(*final_tidy)(IRSB*) ); 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Core events to track */ 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Part of the core from which this call was made. Useful for determining 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown what kind of error message should be emitted. */ 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { Vg_CoreStartup=1, Vg_CoreSignal, Vg_CoreSysCall, 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This is for platforms where syscall args are passed on the 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // stack; although pre_mem_read is the callback that will be 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // called, such an arg should be treated (with respect to 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // presenting information to the user) as if it was passed in a 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // register, ie. like pre_reg_read. 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vg_CoreSysCallArgInMem, 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vg_CoreTranslate, Vg_CoreClientReq 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } CorePart; 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Events happening in core to track. To be notified, pass a callback 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function to the appropriate function. To ignore an event, don't do 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown anything (the default is for events to be ignored). 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note that most events aren't passed a ThreadId. If the event is one called 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown from generated code (eg. new_mem_stack_*), you can use 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_running_tid)() to find it. Otherwise, it has to be passed in, 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as in pre_mem_read, and so the event signature will require changing. 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Memory events (Nb: to track heap allocation/freeing, a tool must replace 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown malloc() et al. See above how to do this.) 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown These ones occur at startup, upon some signals, and upon some syscalls. 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For new_mem_brk and new_mem_stack_signal, the supplied ThreadId 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown indicates the thread for whom the new memory is being allocated. 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For new_mem_startup and new_mem_mmap, the di_handle argument is a 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown handle which can be used to retrieve debug info associated with the 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mapping or allocation (because it is of a file that Valgrind has 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown decided to read debug info from). If the value is zero, there is 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown no associated debug info. If the value exceeds zero, it can be 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown supplied as an argument to selected queries in m_debuginfo. 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_startup) (void(*f)(Addr a, SizeT len, 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool rr, Bool ww, Bool xx, 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong di_handle)); 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_signal)(void(*f)(Addr a, SizeT len, ThreadId tid)); 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_brk) (void(*f)(Addr a, SizeT len, ThreadId tid)); 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_mmap) (void(*f)(Addr a, SizeT len, 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool rr, Bool ww, Bool xx, 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong di_handle)); 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_copy_mem_remap) (void(*f)(Addr from, Addr to, SizeT len)); 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_change_mem_mprotect) (void(*f)(Addr a, SizeT len, 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool rr, Bool ww, Bool xx)); 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_signal)(void(*f)(Addr a, SizeT len)); 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_brk) (void(*f)(Addr a, SizeT len)); 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_munmap) (void(*f)(Addr a, SizeT len)); 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These ones are called when SP changes. A tool could track these itself 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (except for ban_mem_stack) but it's much easier to use the core's help. 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The specialised ones are called in preference to the general one, if they 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are defined. These functions are called a lot if they are used, so 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown specialising can optimise things significantly. If any of the 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown specialised cases are defined, the general case must be defined too. 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Nb: all the specialised ones must use the VG_REGPARM(n) attribute. 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For the _new functions, a tool may specify with with-ECU 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ExeContext Unique) or without-ECU version for each size, but not 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown both. If the with-ECU version is supplied, then the core will 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arrange to pass, as the ecu argument, a 32-bit int which uniquely 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown identifies the instruction moving the stack pointer down. This 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32-bit value is as obtained from VG_(get_ECU_from_ExeContext). 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_ExeContext_from_ECU) can then be used to retrieve the 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown associated depth-1 ExeContext for the location. All this 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown complexity is provided to support origin tracking in Memcheck. 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_4_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_8_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_12_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_16_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_32_w_ECU) (VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_112_w_ECU)(VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_128_w_ECU)(VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_144_w_ECU)(VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_160_w_ECU)(VG_REGPARM(2) void(*f)(Addr new_ESP, UInt ecu)); 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_w_ECU) (void(*f)(Addr a, SizeT len, 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt ecu)); 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_4) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_8) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_12) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_16) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_32) (VG_REGPARM(1) void(*f)(Addr new_ESP)); 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_112)(VG_REGPARM(1) void(*f)(Addr new_ESP)); 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_128)(VG_REGPARM(1) void(*f)(Addr new_ESP)); 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_144)(VG_REGPARM(1) void(*f)(Addr new_ESP)); 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack_160)(VG_REGPARM(1) void(*f)(Addr new_ESP)); 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_new_mem_stack) (void(*f)(Addr a, SizeT len)); 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_4) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_8) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_12) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_16) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_32) (VG_REGPARM(1) void(*f)(Addr die_ESP)); 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_112)(VG_REGPARM(1) void(*f)(Addr die_ESP)); 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_128)(VG_REGPARM(1) void(*f)(Addr die_ESP)); 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_144)(VG_REGPARM(1) void(*f)(Addr die_ESP)); 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack_160)(VG_REGPARM(1) void(*f)(Addr die_ESP)); 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_die_mem_stack) (void(*f)(Addr a, SizeT len)); 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Used for redzone at end of thread stacks */ 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_ban_mem_stack) (void(*f)(Addr a, SizeT len)); 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These ones occur around syscalls, signal handling, etc */ 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_mem_read) (void(*f)(CorePart part, ThreadId tid, 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* s, Addr a, SizeT size)); 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_mem_read_asciiz)(void(*f)(CorePart part, ThreadId tid, 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* s, Addr a)); 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_mem_write) (void(*f)(CorePart part, ThreadId tid, 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* s, Addr a, SizeT size)); 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_post_mem_write) (void(*f)(CorePart part, ThreadId tid, 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr a, SizeT size)); 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Register events. Use VG_(set_shadow_state_area)() to set the shadow regs 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for these events. */ 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_reg_read) (void(*f)(CorePart part, ThreadId tid, 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* s, PtrdiffT guest_state_offset, 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT size)); 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_post_reg_write)(void(*f)(CorePart part, ThreadId tid, 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PtrdiffT guest_state_offset, 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT size)); 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This one is called for malloc() et al if they are replaced by a tool. */ 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_post_reg_write_clientcall_return)( 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void(*f)(ThreadId tid, PtrdiffT guest_state_offset, SizeT size, Addr f)); 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Scheduler events (not exhaustive) */ 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Called when 'tid' starts or stops running client code blocks. 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Gives the total dispatched block count at that event. Note, this 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is not the same as 'tid' holding the BigLock (the lock that ensures 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that only one thread runs at a time): a thread can hold the lock 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for other purposes (making translations, etc) yet not be running 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown client blocks. Obviously though, a thread must hold the lock in 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown order to run client code blocks, so the times bracketed by 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'start_client_code'..'stop_client_code' are a subset of the times 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown when thread 'tid' holds the cpu lock. 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_start_client_code)( 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void(*f)(ThreadId tid, ULong blocks_dispatched) 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_stop_client_code)( 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void(*f)(ThreadId tid, ULong blocks_dispatched) 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Thread events (not exhaustive) 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ll_create: low level thread creation. Called before the new thread 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown has run any instructions (or touched any memory). In fact, called 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown immediately before the new thread has come into existence; the new 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thread can be assumed to exist when notified by this call. 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ll_exit: low level thread exit. Called after the exiting thread 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown has run its last instruction. 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The _ll_ part makes it clear these events are not to do with 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_create or pthread_exit/pthread_join (etc), which are a 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown higher level abstraction synthesised by libpthread. What you can 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be sure of from _ll_create/_ll_exit is the absolute limits of each 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thread's lifetime, and hence be assured that all memory references 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown made by the thread fall inside the _ll_create/_ll_exit pair. This 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is important for tools that need a 100% accurate account of which 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thread is responsible for every memory reference in the process. 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_create/join/exit do not give this property. Calls/returns 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to/from them happen arbitrarily far away from the relevant 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown low-level thread create/quit event. In general a few hundred 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instructions; hence a few hundred(ish) memory references could get 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown misclassified each time. 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pre_thread_first_insn: is called when the thread is all set up and 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ready to go (stack in place, etc) but has not executed its first 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instruction yet. Gives threading tools a chance to ask questions 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown about the thread (eg, what is its initial client stack pointer) 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that are not easily answered at pre_thread_ll_create time. 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For a given thread, the call sequence is: 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ll_create (in the parent's context) 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown first_insn (in the child's context) 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ll_exit (in the child's context) 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_thread_ll_create) (void(*f)(ThreadId tid, ThreadId child)); 666f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanovvoid VG_(track_workq_task_start) (void(*f)(ThreadId tid, Addr workitem)); 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_thread_first_insn)(void(*f)(ThreadId tid)); 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_thread_ll_exit) (void(*f)(ThreadId tid)); 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Signal events (not exhaustive) 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ... pre_send_signal, post_send_signal ... 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Called before a signal is delivered; `alt_stack' indicates if it is 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delivered on an alternative stack. */ 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_pre_deliver_signal) (void(*f)(ThreadId tid, Int sigNo, 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool alt_stack)); 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Called after a signal is delivered. Nb: unfortunately, if the signal 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown handler longjmps, this won't be called. */ 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(track_post_deliver_signal)(void(*f)(ThreadId tid, Int sigNo)); 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // __PUB_TOOL_TOOLIFACE_H 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end ---*/ 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 688