
/*--------------------------------------------------------------------*/
/*--- Function replacement and wrapping.                 m_redir.c ---*/
/*--------------------------------------------------------------------*/

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

   Copyright (C) 2000-2005 Julian Seward 
      jseward@acm.org
   Copyright (C) 2003-2005 Jeremy Fitzhardinge
      jeremy@goop.org

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.

   The GNU General Public License is contained in the file COPYING.
*/

#include "pub_core_basics.h"
#include "pub_core_debuglog.h"
#include "pub_core_debuginfo.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
#include "pub_core_mallocfree.h"
#include "pub_core_options.h"
#include "pub_core_oset.h"
#include "pub_core_redir.h"
#include "pub_core_trampoline.h"
#include "pub_core_transtab.h"

/*------------------------------------------------------------*/
/*--- General purpose redirection.                         ---*/
/*------------------------------------------------------------*/

#define TRACE_REDIR(format, args...) \
   if (VG_(clo_trace_redir)) { VG_(message)(Vg_DebugMsg, format, ## args); }

/*
  wraps and redirections, indexed by from_addr

  Redirection and wrapping are two distinct mechanisms which Valgrind
  can use to change the client's control flow.

  Redirection intercepts a call to a client function, and re-points it
  to a new piece of code (presumably functionally equivalent).  The
  original code is never run.

  Wrapping does call the client's original code, but calls "before"
  and "after" functions which can inspect (and perhaps modify) the
  function's arguments and return value.
 */
struct _CodeRedirect {
   Addr		from_addr;	/* old addr -- MUST BE THE FIRST WORD! */

   enum redir_type {
      R_REDIRECT,		/* plain redirection */
      R_WRAPPER,		/* wrap with valgrind-internal code */
      R_CLIENT_WRAPPER,		/* wrap with client-side code */
   }		type;
   
   const Char	*from_lib;	/* library qualifier pattern */
   const Char	*from_sym;	/* symbol */

   Addr		to_addr;	/* used for redirection -- new addr */
   const FuncWrapper *wrapper;  /* used for wrapping */

   CodeRedirect *next;	        /* next pointer on unresolved list */
};

static OSet* resolved_redirs;

// We use a linked list here rather than an OSet, because we want to
// traverse it and possibly remove elements as we look at them.  OSet
// doesn't support this very well.
static CodeRedirect *unresolved_redirs = NULL;

static Bool soname_matches(const Char *pattern, const Char* soname)
{
   // pattern must start with "soname:"
   vg_assert(NULL != pattern);
   vg_assert(0 == VG_(strncmp)(pattern, "soname:", 7));

   if (NULL == soname)
      return False;
   
   return VG_(string_match)(pattern + 7, soname);
}

Bool VG_(is_resolved)(const CodeRedirect *redir)
{
   return redir->from_addr != 0;
}

// Prepends redir to the unresolved list.
static void add_redir_to_unresolved_list(CodeRedirect *redir)
{
   redir->next = unresolved_redirs;
   unresolved_redirs = redir;
}

static void add_redir_to_resolved_list(CodeRedirect *redir, Bool need_discard)
{
   vg_assert(redir->from_addr);

   switch (redir->type) {
   case R_REDIRECT: {
      TRACE_REDIR("  redir resolved (%s:%s=%p -> %p)", 
                  redir->from_lib, redir->from_sym, redir->from_addr,
                  redir->to_addr);

      vg_assert(redir->to_addr != 0);

      if (need_discard) {
         /* For some given (from, to) redir, the "from" function got
            loaded before the .so containing "to" became available so
            we need to discard any existing translations involving
            the "from" function.

            Note, we only really need to discard the first bb of the
            old entry point, and so we avoid the problem of having to
            figure out how big that bb was -- since it is at least 1
            byte of original code, we can just pass 1 as the original
            size to invalidate_translations() and it will indeed get
            rid of the translation. 

            Note, this is potentially expensive -- discarding
            translations requires a complete search through all of
            them.
         */
         TRACE_REDIR("Discarding translation due to redirect of already loaded function" );
         TRACE_REDIR("   %s:%s(%p) -> %p)", redir->from_lib, redir->from_sym,
                                            redir->from_addr, redir->to_addr );
         VG_(discard_translations)((Addr64)redir->from_addr, 1, 
                                   "add_redir_to_resolved_list");
      }

      // This entails a possible double OSet lookup -- one for Contains(),
      // one for Insert().  If we had OSet_InsertIfNonDup() we could do it
      // with one lookup.
      if ( ! VG_(OSet_Contains)(resolved_redirs, &redir->from_addr) ) {
         VG_(OSet_Insert)(resolved_redirs, redir);
      } else {
         TRACE_REDIR("  redir %s:%s:%p->%p duplicated\n",
                     redir->from_lib, redir->from_sym, redir->from_addr,
                     redir->to_addr);
         VG_(arena_free)(VG_AR_SYMTAB, redir);
      }
      break;
   }

   case R_WRAPPER:
      TRACE_REDIR("  wrapper resolved (%s:%s=%p -> wrapper)",
                  redir->from_lib, redir->from_sym, redir->from_addr);

      vg_assert(redir->wrapper);

      /* XXX redir leaked */
      //VG_(wrap_function)(redir->from_addr, redir->wrapper);
      break;

   case R_CLIENT_WRAPPER:
      vg_assert(redir->wrapper);
      VG_(core_panic)("not implemented");
      break;
   }
}

// Resolve a redir using si if possible.  Returns True if it succeeded.
static Bool resolve_redir_with_seginfo(CodeRedirect *redir, const SegInfo *si)
{
   Bool ok;

   vg_assert(si != NULL);
   vg_assert(redir->from_addr == 0 );
   vg_assert(redir->from_sym  != NULL);

   // Resolved if the soname matches and we find the symbol.
   ok = soname_matches(redir->from_lib, VG_(seginfo_soname)(si));
   if (ok) {
      redir->from_addr = VG_(reverse_search_one_symtab)(si, redir->from_sym);
      ok = ( redir->from_addr == 0 ? False : True );
   }
   return ok;   
}

// Resolve a redir using any SegInfo if possible.  This is called whenever
// a new sym-to-addr redir is created.  It covers the case where a
// replacement function is loaded after its replacee.
static Bool resolve_redir_with_existing_seginfos(CodeRedirect *redir)
{
   const SegInfo *si;

   for (si = VG_(next_seginfo)(NULL); 
        si != NULL; 
        si = VG_(next_seginfo)(si))
   {
      if (resolve_redir_with_seginfo(redir, si))
	 return True;
   }
   return False;
}

// Resolve as many unresolved redirs as possible with this SegInfo.  This
// should be called when a new SegInfo symtab is loaded.  It covers the case
// where a replacee function is loaded after its replacement function.
void VG_(resolve_existing_redirs_with_seginfo)(SegInfo *si)
{
   CodeRedirect **prevp = &unresolved_redirs;
   CodeRedirect *redir, *next;

   TRACE_REDIR("Just loaded %s (soname=%s),",
               VG_(seginfo_filename)(si), VG_(seginfo_soname)(si));
   TRACE_REDIR(" resolving any unresolved redirs with it");

   // Visit each unresolved redir - if it becomes resolved, then
   // move it from the unresolved list to the resolved list.
   for (redir = unresolved_redirs; redir != NULL; redir = next) {
      next = redir->next;

      if (resolve_redir_with_seginfo(redir, si)) {
	 *prevp = next;
	 redir->next = NULL;
         add_redir_to_resolved_list(redir, False);
      } else
	 prevp = &redir->next;
   }

   TRACE_REDIR(" Finished resolving");
}

/* Redirect a function at from_addr to a function at to_addr */
__attribute__((unused))    // It is used, but not on all platforms...
static void add_redirect_addr_to_addr( Addr from_addr, Addr to_addr )
{
   CodeRedirect* redir = VG_(OSet_AllocNode)(resolved_redirs,
                                             sizeof(CodeRedirect));
   vg_assert(0 != from_addr && 0 != to_addr);

   redir->type      = R_REDIRECT;

   redir->from_lib  = NULL;
   redir->from_sym  = NULL;
   redir->from_addr = from_addr;

   redir->to_addr   = to_addr;
   redir->wrapper   = 0;

   TRACE_REDIR("REDIRECT addr to addr: %p to %p", from_addr, to_addr);

   // This redirection is already resolved, put it straight in the list.
   add_redir_to_resolved_list(redir, True);
}

/* Redirect a lib/symbol reference to a function at addr */
static void add_redirect_sym_to_addr(
   const Char *from_lib, const Char *from_sym, Addr to_addr
)
{
   CodeRedirect* redir = VG_(OSet_AllocNode)(resolved_redirs,
                                             sizeof(CodeRedirect));
   vg_assert(from_lib && from_sym && 0 != to_addr);

   redir->type      = R_REDIRECT;
   redir->from_lib  = VG_(arena_strdup)(VG_AR_SYMTAB, from_lib);
   redir->from_sym  = VG_(arena_strdup)(VG_AR_SYMTAB, from_sym);
   redir->from_addr = 0;
   redir->to_addr   = to_addr;
   redir->wrapper   = 0;

   TRACE_REDIR("REDIR sym to addr: %s:%s to %p", from_lib, from_sym, to_addr);

   // Check against all existing segments to see if this redirection
   // can be resolved immediately (as will be the case when the replacement
   // function is loaded after the replacee).  Then add it to the
   // appropriate list.
   if (resolve_redir_with_existing_seginfos(redir)) {
      add_redir_to_resolved_list(redir, True);
   } else {
      add_redir_to_unresolved_list(redir);
   }
}

CodeRedirect *VG_(add_wrapper)(const Char *from_lib, const Char *from_sym,
			       const FuncWrapper *wrapper)
{
   CodeRedirect* redir = VG_(OSet_AllocNode)(resolved_redirs,
                                             sizeof(CodeRedirect));
   redir->type      = R_WRAPPER;
   redir->from_lib  = VG_(arena_strdup)(VG_AR_SYMTAB, from_lib);
   redir->from_sym  = VG_(arena_strdup)(VG_AR_SYMTAB, from_sym);
   redir->from_addr = 0;
   redir->to_addr   = 0;
   redir->wrapper   = wrapper;
   
   TRACE_REDIR("REDIR sym to wrapper: %s:%s to (%p,%p)",
               from_lib, from_sym, wrapper->before, wrapper->after);

   // Check against all existing segments to see if this redirection
   // can be resolved immediately.  Then add it to the appropriate list.
   if (resolve_redir_with_existing_seginfos(redir)) {
      add_redir_to_resolved_list(redir, True);
   } else {
      add_redir_to_unresolved_list(redir);
   }

   return redir;
}

/* If address 'a' is being redirected, return the redirected-to
   address. */
Addr VG_(code_redirect)(Addr a)
{
   CodeRedirect* r = VG_(OSet_Lookup)(resolved_redirs, &a);
   if (r == NULL)
      return a;

   vg_assert(r->to_addr != 0);

   return r->to_addr;
}

static void* symtab_alloc(SizeT n)
{
   return VG_(arena_malloc)(VG_AR_SYMTAB, n);
}

static void symtab_free(void* p)
{
   return VG_(arena_free)(VG_AR_SYMTAB, p);
}

void VG_(setup_code_redirect_table) ( void )
{
   // Initialise resolved_redirs list.
   resolved_redirs = VG_(OSet_Create)(offsetof(CodeRedirect, from_addr),
                                      NULL,     // Use fast comparison
                                      symtab_alloc,
                                      symtab_free);

#if defined(VGP_x86_linux)
   /* Redirect _dl_sysinfo_int80, which is glibc's default system call
      routine, to our copy so that the special sysinfo unwind hack in
      m_stacktrace.c will kick in.  */
   add_redirect_sym_to_addr(
      "soname:ld-linux.so.2", "_dl_sysinfo_int80",
      (Addr)&VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80)
   );

#elif defined(VGP_amd64_linux)

   /* Redirect vsyscalls to local versions */
   add_redirect_addr_to_addr(
      0xFFFFFFFFFF600000ULL,
      (Addr)&VG_(amd64_linux_REDIR_FOR_vgettimeofday) 
   );
   add_redirect_addr_to_addr( 
      0xFFFFFFFFFF600400ULL,
      (Addr)&VG_(amd64_linux_REDIR_FOR_vtime) 
   );

#elif defined(VGP_ppc32_linux)

   add_redirect_sym_to_addr(
      "soname:ld.so.1", "strlen",
      (Addr)&VG_(ppc32_linux_REDIR_FOR_strlen)
   );   
   add_redirect_sym_to_addr(
      "soname:ld.so.1", "strcmp",
      (Addr)&VG_(ppc32_linux_REDIR_FOR_strcmp)
   );   

#else
#  error Unknown platform
#endif
}

/* Z-decode a symbol into library:func form, eg 
  
     _vgi_libcZdsoZd6__ZdlPv  -->  libc.so.6:_ZdlPv

   Uses the Z-encoding scheme described in pub_core_redir.h.
   Returns True if demangle OK, False otherwise.
*/
static Bool Z_decode(const Char* symbol, Char* result, Int nbytes)
{
#  define EMIT(ch)                    \
      do {                            \
         if (j >= nbytes)             \
            result[j-1] = 0;          \
         else                         \
            result[j++] = ch;         \
      } while (0)

   Bool error = False;
   Int i, j = 0;
   Int len = VG_(strlen)(symbol);
   if (0) VG_(printf)("idm: %s\n", symbol);

   i = VG_REPLACE_FUNCTION_PREFIX_LEN;

   /* Chew though the Z-encoded soname part. */
   while (True) {

      if (i >= len) 
         break;

      if (symbol[i] == '_')
         /* We found the underscore following the Z-encoded soname.
            Just copy the rest literally. */
         break;

      if (symbol[i] != 'Z') {
         EMIT(symbol[i]);
         i++;
         continue;
      }

      /* We've got a Z-escape.  Act accordingly. */
      i++;
      if (i >= len) {
         /* Hmm, Z right at the end.  Something's wrong. */
         error = True;
         EMIT('Z');
         break;
      }
      switch (symbol[i]) {
         case 'a': EMIT('*'); break;
         case 'p': EMIT('+'); break;
         case 'c': EMIT(':'); break;
         case 'd': EMIT('.'); break;
         case 'u': EMIT('_'); break;
         case 'h': EMIT('-'); break;
         case 's': EMIT(' '); break;
         case 'Z': EMIT('Z'); break;
         default: error = True; EMIT('Z'); EMIT(symbol[i]); break;
      }
      i++;
   }

   if (error || i >= len || symbol[i] != '_') {
      /* Something's wrong.  Give up. */
      VG_(message)(Vg_UserMsg, "intercept: error demangling: %s", symbol);
      EMIT(0);
      return False;
   }

   /* Copy the rest of the string verbatim. */
   i++;
   EMIT(':');
   while (True) {
     if (i >= len)
        break;
     EMIT(symbol[i]);
     i++;
   }

   EMIT(0);
   if (0) VG_(printf)("%s\n", result);
   return True;

#  undef EMIT
}

// Nb: this can change the string pointed to by 'symbol'.
static void handle_replacement_function( Char* symbol, Addr addr )
{
   Bool ok;
   Int  len  = VG_(strlen)(symbol) + 1 - VG_REPLACE_FUNCTION_PREFIX_LEN;
   Char *lib = VG_(arena_malloc)(VG_AR_SYMTAB, len+8);
   Char *func;

   // Put "soname:" at the start of lib
   VG_(strcpy)(lib, "soname:");

   ok = Z_decode(symbol, lib+7, len);
   if (ok) {
      // lib is "soname:<libname>:<fnname>".  Split the string at the 2nd ':'.
      func = lib + VG_(strlen)(lib)-1;
      while(*func != ':') func--;
      *func = '\0';
      func++;           // Move past the '\0'

      // Now lib is "soname:<libname>" and func is "<fnname>".
      if (0) VG_(printf)("lib A%sZ, func A%sZ\n", lib, func);
      add_redirect_sym_to_addr(lib, func, addr);

      // Overwrite the given Z-encoded name with just the fnname.
      VG_(strcpy)(symbol, func);
   }

   VG_(arena_free)(VG_AR_SYMTAB, lib);
}

static Addr __libc_freeres_wrapper = 0;

Addr VG_(get_libc_freeres_wrapper)(void)
{
   return __libc_freeres_wrapper;
}

// This is specifically for stringifying VG_(x) function names.  We
// need to do two macroexpansions to get the VG_ macro expanded before
// stringifying.
#define _STR(x) #x
#define STR(x)  _STR(x)

static void handle_load_notifier( Char* symbol, Addr addr )
{
   if (VG_(strcmp)(symbol, STR(VG_NOTIFY_ON_LOAD(freeres))) == 0)
      __libc_freeres_wrapper = addr;
//   else if (VG_(strcmp)(symbol, STR(VG_WRAPPER(pthread_startfunc_wrapper))) == 0)
//      VG_(pthread_startfunc_wrapper)((Addr)(si->offset + sym->st_value));
   else
      vg_assert2(0, "unrecognised load notification function: %s", symbol);
}

static Bool is_replacement_function(Char* s)
{
   return (0 == VG_(strncmp)(s,
                             VG_REPLACE_FUNCTION_PREFIX,
                             VG_REPLACE_FUNCTION_PREFIX_LEN));
}

static Bool is_load_notifier(Char* s)
{
   return (0 == VG_(strncmp)(s,
                             VG_NOTIFY_ON_LOAD_PREFIX,
                             VG_NOTIFY_ON_LOAD_PREFIX_LEN));
}

// Call this for each symbol loaded.  It determines if we need to do
// anything special with it.  It can modify 'symbol' in-place.
void VG_(maybe_redir_or_notify) ( Char* symbol, Addr addr )
{
   if (is_replacement_function(symbol))
      handle_replacement_function(symbol, addr);
   else 
   if (is_load_notifier(symbol))
      handle_load_notifier(symbol, addr);
}


//:: /*------------------------------------------------------------*/
//:: /*--- General function wrapping.                           ---*/
//:: /*------------------------------------------------------------*/
//:: 
//:: /* 
//::    TODO:
//::    - hook into the symtab machinery
//::    - client-side wrappers?
//::    - better interfaces for before() functions to get to arguments
//::    - handle munmap of code (dlclose())
//::    - handle thread exit
//::    - handle longjmp
//::  */
//:: struct callkey {
//::    ThreadId	tid;		/* calling thread	    */
//::    Addr		esp;		/* address of args on stack */
//::    Addr		eip;		/* return address	    */
//:: };
//:: 
//:: struct call_instance {
//::    struct callkey key;
//:: 
//::    const FuncWrapper	*wrapper;
//::    void		*nonce;
//:: };
//:: 
//:: static inline Addr addrcmp(Addr a, Addr b)
//:: {
//::    if (a < b)
//::       return -1;
//::    else if (a > b)
//::       return 1;
//::    else 
//::       return 0;
//:: }
//:: 
//:: static inline Int cmp(UInt a, UInt b)
//:: {
//::    if (a < b)
//::       return -1;
//::    else if (a > b)
//::       return 1;
//::    else 
//::       return 0;
//:: }
//:: 
//:: static Int keycmp(const void *pa, const void *pb)
//:: {
//::    const struct callkey *a = (const struct callkey *)pa;
//::    const struct callkey *b = (const struct callkey *)pb;
//::    Int ret;
//:: 
//::    if ((ret = cmp(a->tid, b->tid)))
//::       return ret;
//:: 
//::    if ((ret = addrcmp(a->esp, b->esp)))
//::       return ret;
//:: 
//::    return addrcmp(a->eip, b->eip);
//:: }
//:: 
//:: /* List of wrapped call invocations which are currently active */
//:: static SkipList wrapped_frames = VG_SKIPLIST_INIT(struct call_instance, key, keycmp, 
//:: 					       NULL, VG_AR_SYMTAB);
//:: 
//:: static struct call_instance *find_call(Addr retaddr, Addr argsp, ThreadId tid)
//:: {
//::    struct callkey key = { tid, argsp, retaddr };
//:: 
//::    return VG_(SkipList_Find_Exact)(&wrapped_frames, &key);
//:: }
//:: 
//:: static void wrapper_return(Addr retaddr);
//:: 
//:: /* Called from generated code via helper */
//:: void VG_(wrap_before)(ThreadState *tst, const FuncWrapper *wrapper)
//:: {
//::    Addr retaddr = VG_RETADDR(tst->arch);
//::    Addr argp = (Addr)&VG_FUNC_ARG(tst->arch, 0);
//::    void *nonce = NULL;
//::    Bool mf = VG_(my_fault);
//::    VG_(my_fault) = True;
//:: 
//::    if (wrapper->before) {
//::       va_list args = VG_VA_LIST(tst->arch);
//::       nonce = (*wrapper->before)(args);
//::    }
//:: 
//::    if (wrapper->after) {
//::       /* If there's an after function, make sure it gets called */
//::       struct call_instance *call;
//:: 
//::       call = find_call(retaddr, argp, tst->tid);
//:: 
//::       if (call != NULL) {
//:: 	 /* Found a stale outstanding call; clean it up and recycle
//:: 	    the structure */
//:: 	 if (call->wrapper->after)
//:: 	    (*call->wrapper->after)(call->nonce, RT_LONGJMP, 0);
//::       } else {
//:: 	 call = VG_(SkipNode_Alloc)(&wrapped_frames);
//:: 	 
//:: 	 call->key.tid = tst->tid;
//:: 	 call->key.esp = argp;
//:: 	 call->key.eip = retaddr;
//:: 
//:: 	 VG_(SkipList_Insert)(&wrapped_frames, call);
//:: 
//:: 	 wrapper_return(retaddr);
//::       }
//:: 
//::       call->wrapper = wrapper;
//::       call->nonce = nonce;
//::    } else 
//::       vg_assert(nonce == NULL);
//:: 
//::    VG_(my_fault) = mf;
//:: }
//:: 
//:: /* Called from generated code via helper */
//:: void VG_(wrap_after)(ThreadState *tst)
//:: {
//::    Addr EIP = VG_INSTR_PTR(tst->arch);	/* instruction after call */
//::    Addr ESP = VG_STACK_PTR(tst->arch);	/* pointer to args */
//::    Word ret = VG_RETVAL(tst->arch);		/* return value */
//::    struct call_instance *call;
//::    Bool mf = VG_(my_fault);
//:: 
//::    VG_(my_fault) = True;
//::    call = find_call(EIP, ESP, tst->tid);
//:: 
//::    if (0)
//::       VG_(printf)("wrap_after(%p,%p,%d) -> %p\n", EIP, ESP, tst->tid, call);
//:: 
//::    if (call != NULL) {
//::       if (call->wrapper->after)
//:: 	 (*call->wrapper->after)(call->nonce, RT_RETURN, ret);
//:: 
//::       VG_(SkipList_Remove)(&wrapped_frames, &call->key);
//::       VG_(SkipNode_Free)(&wrapped_frames, call);
//::    }
//::    VG_(my_fault) = mf;
//:: }
//:: 
//:: 
//:: struct wrapped_function {
//::    Addr	eip;			/* eip of function entrypoint */
//::    const FuncWrapper *wrapper;
//:: };
//:: 
//:: struct wrapper_return {
//::    Addr eip;			/* return address */
//:: };
//:: 
//:: /* A mapping from eip of wrapped function entrypoints to actual wrappers */
//:: static SkipList wrapped_functions = VG_SKIPLIST_INIT(struct wrapped_function, eip, VG_(cmp_Addr),
//:: 						  NULL, VG_AR_SYMTAB);
//:: 
//:: /* A set of EIPs which are return addresses for wrapped functions */
//:: static SkipList wrapper_returns = VG_SKIPLIST_INIT(struct wrapper_return, eip, VG_(cmp_Addr),
//:: 						NULL, VG_AR_SYMTAB);
//:: 
//:: /* Wrap function starting at eip */
//:: void VG_(wrap_function)(Addr eip, const FuncWrapper *wrapper)
//:: {
//::    struct wrapped_function *func;
//:: 
//::    if (0)
//::       VG_(printf)("wrapping %p with (%p,%p)\n", eip, wrapper->before, wrapper->after);
//:: 
//::    func = VG_(SkipList_Find_Exact)(&wrapped_functions, &eip);
//:: 
//::    if (func == NULL) {
//::       func = VG_(SkipNode_Alloc)(&wrapped_functions);
//::       VG_(invalidate_translations)(eip, 1, True);
//:: 
//::       func->eip = eip;
//::       VG_(SkipList_Insert)(&wrapped_functions, func);
//::    }
//:: 
//::    func->wrapper = wrapper;
//:: }
//:: 
//:: const FuncWrapper *VG_(is_wrapped)(Addr eip)
//:: {
//::    struct wrapped_function *func = VG_(SkipList_Find_Exact)(&wrapped_functions, &eip);
//:: 
//::    if (func)
//::       return func->wrapper;
//::    return NULL;
//:: }
//:: 
//:: Bool VG_(is_wrapper_return)(Addr eip)
//:: {
//::    struct wrapper_return *ret = VG_(SkipList_Find_Exact)(&wrapper_returns, &eip);
//:: 
//::    return ret != NULL;
//:: }
//:: 
//:: /* Mark eip as being the return address of a wrapper, so that the
//::    codegen will generate the appropriate call. */
//:: void wrapper_return(Addr eip)
//:: {
//::    struct wrapper_return *ret;
//:: 
//::    if (VG_(is_wrapper_return)(eip))
//::       return;
//:: 
//::    VG_(invalidate_translations)(eip, 1, True);
//:: 
//::    ret = VG_(SkipNode_Alloc)(&wrapper_returns);
//::    ret->eip = eip;
//:: 
//::    VG_(SkipList_Insert)(&wrapper_returns, ret);
//:: }

/*--------------------------------------------------------------------*/
/*--- end                                                          ---*/
/*--------------------------------------------------------------------*/
