
/*--------------------------------------------------------------------*/
/*--- Helgrind: a Valgrind tool for detecting errors               ---*/
/*--- in threaded programs.                              hg_main.c ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Helgrind, a Valgrind tool for detecting errors
   in threaded programs.

   Copyright (C) 2007-2015 OpenWorks LLP
      info@open-works.co.uk

   Copyright (C) 2007-2015 Apple, Inc.

   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.

   Neither the names of the U.S. Department of Energy nor the
   University of California nor the names of its contributors may be
   used to endorse or promote products derived from this software
   without prior written permission.
*/

#include "pub_tool_basics.h"
#include "pub_tool_gdbserver.h"
#include "pub_tool_libcassert.h"
#include "pub_tool_libcbase.h"
#include "pub_tool_libcprint.h"
#include "pub_tool_threadstate.h"
#include "pub_tool_tooliface.h"
#include "pub_tool_hashtable.h"
#include "pub_tool_replacemalloc.h"
#include "pub_tool_machine.h"
#include "pub_tool_options.h"
#include "pub_tool_xarray.h"
#include "pub_tool_stacktrace.h"
#include "pub_tool_wordfm.h"
#include "pub_tool_debuginfo.h" // VG_(find_seginfo), VG_(seginfo_soname)
#include "pub_tool_redir.h"     // sonames for the dynamic linkers
#include "pub_tool_vki.h"       // VKI_PAGE_SIZE
#include "pub_tool_libcproc.h"
#include "pub_tool_aspacemgr.h" // VG_(am_is_valid_for_client)
#include "pub_tool_poolalloc.h"
#include "pub_tool_addrinfo.h"

#include "hg_basics.h"
#include "hg_wordset.h"
#include "hg_addrdescr.h"
#include "hg_lock_n_thread.h"
#include "hg_errors.h"

#include "libhb.h"

#include "helgrind.h"


// FIXME: new_mem_w_tid ignores the supplied tid. (wtf?!)

// FIXME: when client destroys a lock or a CV, remove these
// from our mappings, so that the associated SO can be freed up

/*----------------------------------------------------------------*/
/*---                                                          ---*/
/*----------------------------------------------------------------*/

/* Note this needs to be compiled with -fno-strict-aliasing, since it
   contains a whole bunch of calls to lookupFM etc which cast between
   Word and pointer types.  gcc rightly complains this breaks ANSI C
   strict aliasing rules, at -O2.  No complaints at -O, but -O2 gives
   worthwhile performance benefits over -O.
*/

// FIXME what is supposed to happen to locks in memory which
// is relocated as a result of client realloc?

// FIXME put referencing ThreadId into Thread and get
// rid of the slow reverse mapping function.

// FIXME accesses to NoAccess areas: change state to Excl?

// FIXME report errors for accesses of NoAccess memory?

// FIXME pth_cond_wait/timedwait wrappers.  Even if these fail,
// the thread still holds the lock.

/* ------------ Debug/trace options ------------ */

// 0 for silent, 1 for some stuff, 2 for lots of stuff
#define SHOW_EVENTS 0


static void all__sanity_check ( const HChar* who ); /* fwds */

#define HG_CLI__DEFAULT_MALLOC_REDZONE_SZB 16 /* let's say */

// 0 for none, 1 for dump at end of run
#define SHOW_DATA_STRUCTURES 0


/* ------------ Misc comments ------------ */

// FIXME: don't hardwire initial entries for root thread.
// Instead, let the pre_thread_ll_create handler do this.


/*----------------------------------------------------------------*/
/*--- Primary data structures                                  ---*/
/*----------------------------------------------------------------*/

/* Admin linked list of Threads */
static Thread* admin_threads = NULL;
Thread* get_admin_threads ( void ) { return admin_threads; }

/* Admin double linked list of Locks */
/* We need a double linked list to properly and efficiently
   handle del_LockN. */
static Lock* admin_locks = NULL;

/* Mapping table for core ThreadIds to Thread* */
static Thread** map_threads = NULL; /* Array[VG_N_THREADS] of Thread* */

/* Mapping table for lock guest addresses to Lock* */
static WordFM* map_locks = NULL; /* WordFM LockAddr Lock* */

/* The word-set universes for lock sets. */
static WordSetU* univ_lsets = NULL; /* sets of Lock* */
static WordSetU* univ_laog  = NULL; /* sets of Lock*, for LAOG */
static Int next_gc_univ_laog = 1;
/* univ_laog will be garbaged collected when the nr of element in univ_laog is 
   >= next_gc_univ_laog. */

/* Allow libhb to get at the universe of locksets stored
   here.  Sigh. */
WordSetU* HG_(get_univ_lsets) ( void ) { return univ_lsets; }

/* Allow libhb to get at the list of locks stored here.  Ditto
   sigh. */
Lock* HG_(get_admin_locks) ( void ) { return admin_locks; }


/*----------------------------------------------------------------*/
/*--- Simple helpers for the data structures                   ---*/
/*----------------------------------------------------------------*/

static UWord stats__lockN_acquires = 0;
static UWord stats__lockN_releases = 0;

#if defined(VGO_solaris)
Bool HG_(clo_ignore_thread_creation) = True;
#else
Bool HG_(clo_ignore_thread_creation) = False;
#endif /* VGO_solaris */

static
ThreadId map_threads_maybe_reverse_lookup_SLOW ( Thread* thr ); /*fwds*/

/* --------- Constructors --------- */

static Thread* mk_Thread ( Thr* hbthr ) {
   static Int indx      = 1;
   Thread* thread       = HG_(zalloc)( "hg.mk_Thread.1", sizeof(Thread) );
   thread->locksetA     = HG_(emptyWS)( univ_lsets );
   thread->locksetW     = HG_(emptyWS)( univ_lsets );
   thread->magic        = Thread_MAGIC;
   thread->hbthr        = hbthr;
   thread->coretid      = VG_INVALID_THREADID;
   thread->created_at   = NULL;
   thread->announced    = False;
   thread->errmsg_index = indx++;
   thread->admin        = admin_threads;
   thread->synchr_nesting = 0;
   thread->pthread_create_nesting_level = 0;
#if defined(VGO_solaris)
   thread->bind_guard_flag = 0;
#endif /* VGO_solaris */

   admin_threads        = thread;
   return thread;
}

// Make a new lock which is unlocked (hence ownerless)
// and insert the new lock in admin_locks double linked list.
static Lock* mk_LockN ( LockKind kind, Addr guestaddr ) {
   static ULong unique = 0;
   Lock* lock             = HG_(zalloc)( "hg.mk_Lock.1", sizeof(Lock) );
   /* begin: add to double linked list */
   if (admin_locks)
      admin_locks->admin_prev = lock;
   lock->admin_next       = admin_locks;
   lock->admin_prev       = NULL;
   admin_locks            = lock;
   /* end: add */
   lock->unique           = unique++;
   lock->magic            = LockN_MAGIC;
   lock->appeared_at      = NULL;
   lock->acquired_at      = NULL;
   lock->hbso             = libhb_so_alloc();
   lock->guestaddr        = guestaddr;
   lock->kind             = kind;
   lock->heldW            = False;
   lock->heldBy           = NULL;
   tl_assert(HG_(is_sane_LockN)(lock));
   return lock;
}

/* Release storage for a Lock.  Also release storage in .heldBy, if
   any. Removes from admin_locks double linked list. */
static void del_LockN ( Lock* lk ) 
{
   tl_assert(HG_(is_sane_LockN)(lk));
   tl_assert(lk->hbso);
   libhb_so_dealloc(lk->hbso);
   if (lk->heldBy)
      VG_(deleteBag)( lk->heldBy );
   /* begin: del lock from double linked list */
   if (lk == admin_locks) {
      tl_assert(lk->admin_prev == NULL);
      if (lk->admin_next)
         lk->admin_next->admin_prev = NULL;
      admin_locks = lk->admin_next;
   }
   else {
      tl_assert(lk->admin_prev != NULL);
      lk->admin_prev->admin_next = lk->admin_next;
      if (lk->admin_next)
         lk->admin_next->admin_prev = lk->admin_prev;
   }
   /* end: del */
   VG_(memset)(lk, 0xAA, sizeof(*lk));
   HG_(free)(lk);
}

/* Update 'lk' to reflect that 'thr' now has a write-acquisition of
   it.  This is done strictly: only combinations resulting from
   correct program and libpthread behaviour are allowed. */
static void lockN_acquire_writer ( Lock* lk, Thread* thr ) 
{
   tl_assert(HG_(is_sane_LockN)(lk));
   tl_assert(HG_(is_sane_Thread)(thr));

   stats__lockN_acquires++;

   /* EXPOSITION only */
   /* We need to keep recording snapshots of where the lock was
      acquired, so as to produce better lock-order error messages. */
   if (lk->acquired_at == NULL) {
      ThreadId tid;
      tl_assert(lk->heldBy == NULL);
      tid = map_threads_maybe_reverse_lookup_SLOW(thr);
      lk->acquired_at
         = VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
   } else {
      tl_assert(lk->heldBy != NULL);
   }
   /* end EXPOSITION only */

   switch (lk->kind) {
      case LK_nonRec:
      case_LK_nonRec:
         tl_assert(lk->heldBy == NULL); /* can't w-lock recursively */
         tl_assert(!lk->heldW);
         lk->heldW  = True;
         lk->heldBy = VG_(newBag)( HG_(zalloc), "hg.lNaw.1", HG_(free) );
         VG_(addToBag)( lk->heldBy, (UWord)thr );
         break;
      case LK_mbRec:
         if (lk->heldBy == NULL)
            goto case_LK_nonRec;
         /* 2nd and subsequent locking of a lock by its owner */
         tl_assert(lk->heldW);
         /* assert: lk is only held by one thread .. */
         tl_assert(VG_(sizeUniqueBag(lk->heldBy)) == 1);
         /* assert: .. and that thread is 'thr'. */
         tl_assert(VG_(elemBag)(lk->heldBy, (UWord)thr)
                   == VG_(sizeTotalBag)(lk->heldBy));
         VG_(addToBag)(lk->heldBy, (UWord)thr);
         break;
      case LK_rdwr:
         tl_assert(lk->heldBy == NULL && !lk->heldW); /* must be unheld */
         goto case_LK_nonRec;
      default: 
         tl_assert(0);
  }
  tl_assert(HG_(is_sane_LockN)(lk));
}

static void lockN_acquire_reader ( Lock* lk, Thread* thr )
{
   tl_assert(HG_(is_sane_LockN)(lk));
   tl_assert(HG_(is_sane_Thread)(thr));
   /* can only add reader to a reader-writer lock. */
   tl_assert(lk->kind == LK_rdwr);
   /* lk must be free or already r-held. */
   tl_assert(lk->heldBy == NULL 
             || (lk->heldBy != NULL && !lk->heldW));

   stats__lockN_acquires++;

   /* EXPOSITION only */
   /* We need to keep recording snapshots of where the lock was
      acquired, so as to produce better lock-order error messages. */
   if (lk->acquired_at == NULL) {
      ThreadId tid;
      tl_assert(lk->heldBy == NULL);
      tid = map_threads_maybe_reverse_lookup_SLOW(thr);
      lk->acquired_at
         = VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
   } else {
      tl_assert(lk->heldBy != NULL);
   }
   /* end EXPOSITION only */

   if (lk->heldBy) {
      VG_(addToBag)(lk->heldBy, (UWord)thr);
   } else {
      lk->heldW  = False;
      lk->heldBy = VG_(newBag)( HG_(zalloc), "hg.lNar.1", HG_(free) );
      VG_(addToBag)( lk->heldBy, (UWord)thr );
   }
   tl_assert(!lk->heldW);
   tl_assert(HG_(is_sane_LockN)(lk));
}

/* Update 'lk' to reflect a release of it by 'thr'.  This is done
   strictly: only combinations resulting from correct program and
   libpthread behaviour are allowed. */

static void lockN_release ( Lock* lk, Thread* thr )
{
   Bool b;
   tl_assert(HG_(is_sane_LockN)(lk));
   tl_assert(HG_(is_sane_Thread)(thr));
   /* lock must be held by someone */
   tl_assert(lk->heldBy);
   stats__lockN_releases++;
   /* Remove it from the holder set */
   b = VG_(delFromBag)(lk->heldBy, (UWord)thr);
   /* thr must actually have been a holder of lk */
   tl_assert(b);
   /* normalise */
   tl_assert(lk->acquired_at);
   if (VG_(isEmptyBag)(lk->heldBy)) {
      VG_(deleteBag)(lk->heldBy);
      lk->heldBy      = NULL;
      lk->heldW       = False;
      lk->acquired_at = NULL;
   }
   tl_assert(HG_(is_sane_LockN)(lk));
}

static void remove_Lock_from_locksets_of_all_owning_Threads( Lock* lk )
{
   Thread* thr;
   if (!lk->heldBy) {
      tl_assert(!lk->heldW);
      return;
   }
   /* for each thread that holds this lock do ... */
   VG_(initIterBag)( lk->heldBy );
   while (VG_(nextIterBag)( lk->heldBy, (UWord*)&thr, NULL )) {
      tl_assert(HG_(is_sane_Thread)(thr));
      tl_assert(HG_(elemWS)( univ_lsets,
                             thr->locksetA, (UWord)lk ));
      thr->locksetA
         = HG_(delFromWS)( univ_lsets, thr->locksetA, (UWord)lk );

      if (lk->heldW) {
         tl_assert(HG_(elemWS)( univ_lsets,
                                thr->locksetW, (UWord)lk ));
         thr->locksetW
            = HG_(delFromWS)( univ_lsets, thr->locksetW, (UWord)lk );
      }
   }
   VG_(doneIterBag)( lk->heldBy );
}


/*----------------------------------------------------------------*/
/*--- Print out the primary data structures                    ---*/
/*----------------------------------------------------------------*/

#define PP_THREADS      (1<<1)
#define PP_LOCKS        (1<<2)
#define PP_ALL (PP_THREADS | PP_LOCKS)


static const Int sHOW_ADMIN = 0;

static void space ( Int n )
{
   Int  i;
   HChar spaces[128+1];
   tl_assert(n >= 0 && n < 128);
   if (n == 0)
      return;
   for (i = 0; i < n; i++)
      spaces[i] = ' ';
   spaces[i] = 0;
   tl_assert(i < 128+1);
   VG_(printf)("%s", spaces);
}

static void pp_Thread ( Int d, Thread* t )
{
   space(d+0); VG_(printf)("Thread %p {\n", t);
   if (sHOW_ADMIN) {
   space(d+3); VG_(printf)("admin    %p\n",   t->admin);
   space(d+3); VG_(printf)("magic    0x%x\n", (UInt)t->magic);
   }
   space(d+3); VG_(printf)("locksetA %d\n",   (Int)t->locksetA);
   space(d+3); VG_(printf)("locksetW %d\n",   (Int)t->locksetW);
   space(d+0); VG_(printf)("}\n");
}

static void pp_admin_threads ( Int d )
{
   Int     i, n;
   Thread* t;
   for (n = 0, t = admin_threads;  t;  n++, t = t->admin) {
      /* nothing */
   }
   space(d); VG_(printf)("admin_threads (%d records) {\n", n);
   for (i = 0, t = admin_threads;  t;  i++, t = t->admin) {
      if (0) {
         space(n); 
         VG_(printf)("admin_threads record %d of %d:\n", i, n);
      }
      pp_Thread(d+3, t);
   }
   space(d); VG_(printf)("}\n");
}

static void pp_map_threads ( Int d )
{
   Int i, n = 0;
   space(d); VG_(printf)("map_threads ");
   for (i = 0; i < VG_N_THREADS; i++) {
      if (map_threads[i] != NULL)
         n++;
   }
   VG_(printf)("(%d entries) {\n", n);
   for (i = 0; i < VG_N_THREADS; i++) {
      if (map_threads[i] == NULL)
         continue;
      space(d+3);
      VG_(printf)("coretid %d -> Thread %p\n", i, map_threads[i]);
   }
   space(d); VG_(printf)("}\n");
}

static const HChar* show_LockKind ( LockKind lkk ) {
   switch (lkk) {
      case LK_mbRec:  return "mbRec";
      case LK_nonRec: return "nonRec";
      case LK_rdwr:   return "rdwr";
      default:        tl_assert(0);
   }
}

/* Pretty Print lock lk.
   if show_lock_addrdescr, describes the (guest) lock address.
     (this description will be more complete with --read-var-info=yes).
   if show_internal_data, shows also helgrind internal information. 
   d is the level at which output is indented. */
static void pp_Lock ( Int d, Lock* lk,
                      Bool show_lock_addrdescr,
                      Bool show_internal_data)
{
   space(d+0); 
   if (show_internal_data)
      VG_(printf)("Lock %p (ga %#lx) {\n", lk, lk->guestaddr);
   else
      VG_(printf)("Lock ga %#lx {\n", lk->guestaddr);
   if (!show_lock_addrdescr 
       || !HG_(get_and_pp_addrdescr) ((Addr) lk->guestaddr))
      VG_(printf)("\n");
      
   if (sHOW_ADMIN) {
      space(d+3); VG_(printf)("admin_n  %p\n",   lk->admin_next);
      space(d+3); VG_(printf)("admin_p  %p\n",   lk->admin_prev);
      space(d+3); VG_(printf)("magic    0x%x\n", (UInt)lk->magic);
   }
   if (show_internal_data) {
      space(d+3); VG_(printf)("unique %llu\n", lk->unique);
   }
   space(d+3); VG_(printf)("kind   %s\n", show_LockKind(lk->kind));
   if (show_internal_data) {
      space(d+3); VG_(printf)("heldW  %s\n", lk->heldW ? "yes" : "no");
   }
   if (show_internal_data) {
      space(d+3); VG_(printf)("heldBy %p", lk->heldBy);
   }
   if (lk->heldBy) {
      Thread* thr;
      UWord   count;
      VG_(printf)(" { ");
      VG_(initIterBag)( lk->heldBy );
      while (VG_(nextIterBag)( lk->heldBy, (UWord*)&thr, &count )) {
         if (show_internal_data)
            VG_(printf)("%lu:%p ", count, thr);
         else {
            VG_(printf)("%c%lu:thread #%d ",
                        lk->heldW ? 'W' : 'R',
                        count, thr->errmsg_index);
            if (thr->coretid == VG_INVALID_THREADID) 
               VG_(printf)("tid (exited) ");
            else
               VG_(printf)("tid %u ", thr->coretid);

         }
      }
      VG_(doneIterBag)( lk->heldBy );
      VG_(printf)("}\n");
   }
   space(d+0); VG_(printf)("}\n");
}

static void pp_admin_locks ( Int d )
{
   Int   i, n;
   Lock* lk;
   for (n = 0, lk = admin_locks;  lk;  n++, lk = lk->admin_next) {
      /* nothing */
   }
   space(d); VG_(printf)("admin_locks (%d records) {\n", n);
   for (i = 0, lk = admin_locks;  lk;  i++, lk = lk->admin_next) {
      if (0) {
         space(n); 
         VG_(printf)("admin_locks record %d of %d:\n", i, n);
      }
      pp_Lock(d+3, lk,
              False /* show_lock_addrdescr */,
              True /* show_internal_data */);
   }
   space(d); VG_(printf)("}\n");
}

static void pp_map_locks ( Int d)
{
   void* gla;
   Lock* lk;
   space(d); VG_(printf)("map_locks (%d entries) {\n",
                         (Int)VG_(sizeFM)( map_locks ));
   VG_(initIterFM)( map_locks );
   while (VG_(nextIterFM)( map_locks, (UWord*)&gla,
                                      (UWord*)&lk )) {
      space(d+3);
      VG_(printf)("guest %p -> Lock %p\n", gla, lk);
   }
   VG_(doneIterFM)( map_locks );
   space(d); VG_(printf)("}\n");
}

static void pp_everything ( Int flags, const HChar* caller )
{
   Int d = 0;
   VG_(printf)("\n");
   VG_(printf)("All_Data_Structures (caller = \"%s\") {\n", caller);
   if (flags & PP_THREADS) {
      VG_(printf)("\n");
      pp_admin_threads(d+3);
      VG_(printf)("\n");
      pp_map_threads(d+3);
   }
   if (flags & PP_LOCKS) {
      VG_(printf)("\n");
      pp_admin_locks(d+3);
      VG_(printf)("\n");
      pp_map_locks(d+3);
   }

   VG_(printf)("\n");
   VG_(printf)("}\n");
   VG_(printf)("\n");
}

#undef SHOW_ADMIN


/*----------------------------------------------------------------*/
/*--- Initialise the primary data structures                   ---*/
/*----------------------------------------------------------------*/

static void initialise_data_structures ( Thr* hbthr_root )
{
   Thread*   thr;
   WordSetID wsid;

   /* Get everything initialised and zeroed. */
   tl_assert(admin_threads == NULL);
   tl_assert(admin_locks == NULL);

   tl_assert(map_threads == NULL);
   map_threads = HG_(zalloc)( "hg.ids.1", VG_N_THREADS * sizeof(Thread*) );

   tl_assert(sizeof(Addr) == sizeof(UWord));
   tl_assert(map_locks == NULL);
   map_locks = VG_(newFM)( HG_(zalloc), "hg.ids.2", HG_(free), 
                           NULL/*unboxed Word cmp*/);

   tl_assert(univ_lsets == NULL);
   univ_lsets = HG_(newWordSetU)( HG_(zalloc), "hg.ids.4", HG_(free),
                                  8/*cacheSize*/ );
   tl_assert(univ_lsets != NULL);
   /* Ensure that univ_lsets is non-empty, with lockset zero being the
      empty lockset.  hg_errors.c relies on the assumption that
      lockset number zero in univ_lsets is always valid. */
   wsid = HG_(emptyWS)(univ_lsets);
   tl_assert(wsid == 0);

   tl_assert(univ_laog == NULL);
   if (HG_(clo_track_lockorders)) {
      univ_laog = HG_(newWordSetU)( HG_(zalloc), "hg.ids.5 (univ_laog)",
                                    HG_(free), 24/*cacheSize*/ );
      tl_assert(univ_laog != NULL);
   }

   /* Set up entries for the root thread */
   // FIXME: this assumes that the first real ThreadId is 1

   /* a Thread for the new thread ... */
   thr = mk_Thread(hbthr_root);
   thr->coretid = 1; /* FIXME: hardwires an assumption about the
                        identity of the root thread. */
   tl_assert( libhb_get_Thr_hgthread(hbthr_root) == NULL );
   libhb_set_Thr_hgthread(hbthr_root, thr);

   /* and bind it in the thread-map table. */
   tl_assert(HG_(is_sane_ThreadId)(thr->coretid));
   tl_assert(thr->coretid != VG_INVALID_THREADID);

   map_threads[thr->coretid] = thr;

   tl_assert(VG_INVALID_THREADID == 0);

   all__sanity_check("initialise_data_structures");
}


/*----------------------------------------------------------------*/
/*--- map_threads :: array[core-ThreadId] of Thread*           ---*/
/*----------------------------------------------------------------*/

/* Doesn't assert if the relevant map_threads entry is NULL. */
static Thread* map_threads_maybe_lookup ( ThreadId coretid )
{
   Thread* thr;
   tl_assert( HG_(is_sane_ThreadId)(coretid) );
   thr = map_threads[coretid];
   return thr;
}

/* Asserts if the relevant map_threads entry is NULL. */
static inline Thread* map_threads_lookup ( ThreadId coretid )
{
   Thread* thr;
   tl_assert( HG_(is_sane_ThreadId)(coretid) );
   thr = map_threads[coretid];
   tl_assert(thr);
   return thr;
}

/* Do a reverse lookup.  Does not assert if 'thr' is not found in
   map_threads. */
static ThreadId map_threads_maybe_reverse_lookup_SLOW ( Thread* thr )
{
   ThreadId tid;
   tl_assert(HG_(is_sane_Thread)(thr));
   /* Check nobody used the invalid-threadid slot */
   tl_assert(VG_INVALID_THREADID >= 0 && VG_INVALID_THREADID < VG_N_THREADS);
   tl_assert(map_threads[VG_INVALID_THREADID] == NULL);
   tid = thr->coretid;
   tl_assert(HG_(is_sane_ThreadId)(tid));
   return tid;
}

/* Do a reverse lookup.  Warning: POTENTIALLY SLOW.  Asserts if 'thr'
   is not found in map_threads. */
static ThreadId map_threads_reverse_lookup_SLOW ( Thread* thr )
{
   ThreadId tid = map_threads_maybe_reverse_lookup_SLOW( thr );
   tl_assert(tid != VG_INVALID_THREADID);
   tl_assert(map_threads[tid]);
   tl_assert(map_threads[tid]->coretid == tid);
   return tid;
}

static void map_threads_delete ( ThreadId coretid )
{
   Thread* thr;
   tl_assert(coretid != 0);
   tl_assert( HG_(is_sane_ThreadId)(coretid) );
   thr = map_threads[coretid];
   tl_assert(thr);
   map_threads[coretid] = NULL;
}

static void HG_(thread_enter_synchr)(Thread *thr) {
   tl_assert(thr->synchr_nesting >= 0);
#if defined(VGO_solaris)
   thr->synchr_nesting += 1;
#endif /* VGO_solaris */
}

static void HG_(thread_leave_synchr)(Thread *thr) {
#if defined(VGO_solaris)
   thr->synchr_nesting -= 1;
#endif /* VGO_solaris */
   tl_assert(thr->synchr_nesting >= 0);
}

static void HG_(thread_enter_pthread_create)(Thread *thr) {
   tl_assert(thr->pthread_create_nesting_level >= 0);
   thr->pthread_create_nesting_level += 1;
}

static void HG_(thread_leave_pthread_create)(Thread *thr) {
   tl_assert(thr->pthread_create_nesting_level > 0);
   thr->pthread_create_nesting_level -= 1;
}

static Int HG_(get_pthread_create_nesting_level)(ThreadId tid) {
   Thread *thr = map_threads_maybe_lookup(tid);
   return thr->pthread_create_nesting_level;
}

/*----------------------------------------------------------------*/
/*--- map_locks :: WordFM guest-Addr-of-lock Lock*             ---*/
/*----------------------------------------------------------------*/

/* Make sure there is a lock table entry for the given (lock) guest
   address.  If not, create one of the stated 'kind' in unheld state.
   In any case, return the address of the existing or new Lock. */
static 
Lock* map_locks_lookup_or_create ( LockKind lkk, Addr ga, ThreadId tid )
{
   Bool  found;
   Lock* oldlock = NULL;
   tl_assert(HG_(is_sane_ThreadId)(tid));
   found = VG_(lookupFM)( map_locks, 
                          NULL, (UWord*)&oldlock, (UWord)ga );
   if (!found) {
      Lock* lock = mk_LockN(lkk, ga);
      lock->appeared_at = VG_(record_ExeContext)( tid, 0 );
      tl_assert(HG_(is_sane_LockN)(lock));
      VG_(addToFM)( map_locks, (UWord)ga, (UWord)lock );
      tl_assert(oldlock == NULL);
      return lock;
   } else {
      tl_assert(oldlock != NULL);
      tl_assert(HG_(is_sane_LockN)(oldlock));
      tl_assert(oldlock->guestaddr == ga);
      return oldlock;
   }
}

static Lock* map_locks_maybe_lookup ( Addr ga )
{
   Bool  found;
   Lock* lk = NULL;
   found = VG_(lookupFM)( map_locks, NULL, (UWord*)&lk, (UWord)ga );
   tl_assert(found  ?  lk != NULL  :  lk == NULL);
   return lk;
}

static void map_locks_delete ( Addr ga )
{
   Addr  ga2 = 0;
   Lock* lk  = NULL;
   VG_(delFromFM)( map_locks,
                   (UWord*)&ga2, (UWord*)&lk, (UWord)ga );
   /* delFromFM produces the val which is being deleted, if it is
      found.  So assert it is non-null; that in effect asserts that we
      are deleting a (ga, Lock) pair which actually exists. */
   tl_assert(lk != NULL);
   tl_assert(ga2 == ga);
}



/*----------------------------------------------------------------*/
/*--- Sanity checking the data structures                      ---*/
/*----------------------------------------------------------------*/

static UWord stats__sanity_checks = 0;

static void laog__sanity_check ( const HChar* who ); /* fwds */

/* REQUIRED INVARIANTS:

   Thread vs Segment/Lock/SecMaps

      for each t in Threads {

         // Thread.lockset: each element is really a valid Lock

         // Thread.lockset: each Lock in set is actually held by that thread
         for lk in Thread.lockset 
            lk == LockedBy(t)

         // Thread.csegid is a valid SegmentID
         // and the associated Segment has .thr == t

      }

      all thread Locksets are pairwise empty under intersection
      (that is, no lock is claimed to be held by more than one thread)
      -- this is guaranteed if all locks in locksets point back to their
      owner threads

   Lock vs Thread/Segment/SecMaps

      for each entry (gla, la) in map_locks
         gla == la->guest_addr

      for each lk in Locks {

         lk->tag is valid
         lk->guest_addr does not have shadow state NoAccess
         if lk == LockedBy(t), then t->lockset contains lk
         if lk == UnlockedBy(segid) then segid is valid SegmentID
             and can be mapped to a valid Segment(seg)
             and seg->thr->lockset does not contain lk
         if lk == UnlockedNew then (no lockset contains lk)

         secmaps for lk has .mbHasLocks == True

      }

   Segment vs Thread/Lock/SecMaps

      the Segment graph is a dag (no cycles)
      all of the Segment graph must be reachable from the segids
         mentioned in the Threads

      for seg in Segments {

         seg->thr is a sane Thread

      }

   SecMaps vs Segment/Thread/Lock

      for sm in SecMaps {

         sm properly aligned
         if any shadow word is ShR or ShM then .mbHasShared == True

         for each Excl(segid) state
            map_segments_lookup maps to a sane Segment(seg)
         for each ShM/ShR(tsetid,lsetid) state
            each lk in lset is a valid Lock
            each thr in tset is a valid thread, which is non-dead

      }
*/


/* Return True iff 'thr' holds 'lk' in some mode. */
static Bool thread_is_a_holder_of_Lock ( Thread* thr, Lock* lk )
{
   if (lk->heldBy)
      return VG_(elemBag)( lk->heldBy, (UWord)thr ) > 0;
   else
      return False;
}

/* Sanity check Threads, as far as possible */
__attribute__((noinline))
static void threads__sanity_check ( const HChar* who )
{
#define BAD(_str) do { how = (_str); goto bad; } while (0)
   const HChar* how = "no error";
   Thread*   thr;
   WordSetID wsA, wsW;
   UWord*    ls_words;
   UWord     ls_size, i;
   Lock*     lk;
   for (thr = admin_threads; thr; thr = thr->admin) {
      if (!HG_(is_sane_Thread)(thr)) BAD("1");
      wsA = thr->locksetA;
      wsW = thr->locksetW;
      // locks held in W mode are a subset of all locks held
      if (!HG_(isSubsetOf)( univ_lsets, wsW, wsA )) BAD("7");
      HG_(getPayloadWS)( &ls_words, &ls_size, univ_lsets, wsA );
      for (i = 0; i < ls_size; i++) {
         lk = (Lock*)ls_words[i];
         // Thread.lockset: each element is really a valid Lock
         if (!HG_(is_sane_LockN)(lk)) BAD("2");
         // Thread.lockset: each Lock in set is actually held by that
         // thread
         if (!thread_is_a_holder_of_Lock(thr,lk)) BAD("3");
      }
   }
   return;
  bad:
   VG_(printf)("threads__sanity_check: who=\"%s\", bad=\"%s\"\n", who, how);
   tl_assert(0);
#undef BAD
}


/* Sanity check Locks, as far as possible */
__attribute__((noinline))
static void locks__sanity_check ( const HChar* who )
{
#define BAD(_str) do { how = (_str); goto bad; } while (0)
   const HChar* how = "no error";
   Addr      gla;
   Lock*     lk;
   Int       i;
   // # entries in admin_locks == # entries in map_locks
   for (i = 0, lk = admin_locks;  lk;  i++, lk = lk->admin_next)
      ;
   if (i != VG_(sizeFM)(map_locks)) BAD("1");
   // for each entry (gla, lk) in map_locks
   //      gla == lk->guest_addr
   VG_(initIterFM)( map_locks );
   while (VG_(nextIterFM)( map_locks,
                           (UWord*)&gla, (UWord*)&lk )) {
      if (lk->guestaddr != gla) BAD("2");
   }
   VG_(doneIterFM)( map_locks );
   // scan through admin_locks ...
   for (lk = admin_locks; lk; lk = lk->admin_next) {
      // lock is sane.  Quite comprehensive, also checks that
      // referenced (holder) threads are sane.
      if (!HG_(is_sane_LockN)(lk)) BAD("3");
      // map_locks binds guest address back to this lock
      if (lk != map_locks_maybe_lookup(lk->guestaddr)) BAD("4");
      // look at all threads mentioned as holders of this lock.  Ensure
      // this lock is mentioned in their locksets.
      if (lk->heldBy) {
         Thread* thr;
         UWord   count;
         VG_(initIterBag)( lk->heldBy );
         while (VG_(nextIterBag)( lk->heldBy, 
                                  (UWord*)&thr, &count )) {
            // HG_(is_sane_LockN) above ensures these
            tl_assert(count >= 1);
            tl_assert(HG_(is_sane_Thread)(thr));
            if (!HG_(elemWS)(univ_lsets, thr->locksetA, (UWord)lk)) 
               BAD("6");
            // also check the w-only lockset
            if (lk->heldW 
                && !HG_(elemWS)(univ_lsets, thr->locksetW, (UWord)lk)) 
               BAD("7");
            if ((!lk->heldW)
                && HG_(elemWS)(univ_lsets, thr->locksetW, (UWord)lk)) 
               BAD("8");
         }
         VG_(doneIterBag)( lk->heldBy );
      } else {
         /* lock not held by anybody */
         if (lk->heldW) BAD("9"); /* should be False if !heldBy */
         // since lk is unheld, then (no lockset contains lk)
         // hmm, this is really too expensive to check.  Hmm.
      }
   }

   return;
  bad:
   VG_(printf)("locks__sanity_check: who=\"%s\", bad=\"%s\"\n", who, how);
   tl_assert(0);
#undef BAD
}


static void all_except_Locks__sanity_check ( const HChar* who ) {
   stats__sanity_checks++;
   if (0) VG_(printf)("all_except_Locks__sanity_check(%s)\n", who);
   threads__sanity_check(who);
   if (HG_(clo_track_lockorders))
      laog__sanity_check(who);
}
static void all__sanity_check ( const HChar* who ) {
   all_except_Locks__sanity_check(who);
   locks__sanity_check(who);
}


/*----------------------------------------------------------------*/
/*--- Shadow value and address range handlers                  ---*/
/*----------------------------------------------------------------*/

static void laog__pre_thread_acquires_lock ( Thread*, Lock* ); /* fwds */
//static void laog__handle_lock_deletions    ( WordSetID ); /* fwds */
static inline Thread* get_current_Thread ( void ); /* fwds */
__attribute__((noinline))
static void laog__handle_one_lock_deletion ( Lock* lk ); /* fwds */


/* Block-copy states (needed for implementing realloc()). */
/* FIXME this copies shadow memory; it doesn't apply the MSM to it.
   Is that a problem? (hence 'scopy' rather than 'ccopy') */
static void shadow_mem_scopy_range ( Thread* thr,
                                     Addr src, Addr dst, SizeT len )
{
   Thr*     hbthr = thr->hbthr;
   tl_assert(hbthr);
   libhb_copy_shadow_state( hbthr, src, dst, len );
}

static void shadow_mem_cread_range ( Thread* thr, Addr a, SizeT len )
{
   Thr*     hbthr = thr->hbthr;
   tl_assert(hbthr);
   LIBHB_CREAD_N(hbthr, a, len);
}

static void shadow_mem_cwrite_range ( Thread* thr, Addr a, SizeT len ) {
   Thr*     hbthr = thr->hbthr;
   tl_assert(hbthr);
   LIBHB_CWRITE_N(hbthr, a, len);
}

static void shadow_mem_make_New ( Thread* thr, Addr a, SizeT len )
{
   libhb_srange_new( thr->hbthr, a, len );
}

static void shadow_mem_make_NoAccess_NoFX ( Thread* thr, Addr aIN, SizeT len )
{
   if (0 && len > 500)
      VG_(printf)("make NoAccess_NoFX ( %#lx, %lu )\n", aIN, len );
   // has no effect (NoFX)
   libhb_srange_noaccess_NoFX( thr->hbthr, aIN, len );
}

static void shadow_mem_make_NoAccess_AHAE ( Thread* thr, Addr aIN, SizeT len )
{
   if (0 && len > 500)
      VG_(printf)("make NoAccess_AHAE ( %#lx, %lu )\n", aIN, len );
   // Actually Has An Effect (AHAE)
   libhb_srange_noaccess_AHAE( thr->hbthr, aIN, len );
}

static void shadow_mem_make_Untracked ( Thread* thr, Addr aIN, SizeT len )
{
   if (0 && len > 500)
      VG_(printf)("make Untracked ( %#lx, %lu )\n", aIN, len );
   libhb_srange_untrack( thr->hbthr, aIN, len );
}


/*----------------------------------------------------------------*/
/*--- Event handlers (evh__* functions)                        ---*/
/*--- plus helpers (evhH__* functions)                         ---*/
/*----------------------------------------------------------------*/

/*--------- Event handler helpers (evhH__* functions) ---------*/

/* Create a new segment for 'thr', making it depend (.prev) on its
   existing segment, bind together the SegmentID and Segment, and
   return both of them.  Also update 'thr' so it references the new
   Segment. */
//zz static 
//zz void evhH__start_new_segment_for_thread ( /*OUT*/SegmentID* new_segidP,
//zz                                           /*OUT*/Segment** new_segP,
//zz                                           Thread* thr )
//zz {
//zz    Segment* cur_seg;
//zz    tl_assert(new_segP);
//zz    tl_assert(new_segidP);
//zz    tl_assert(HG_(is_sane_Thread)(thr));
//zz    cur_seg = map_segments_lookup( thr->csegid );
//zz    tl_assert(cur_seg);
//zz    tl_assert(cur_seg->thr == thr); /* all sane segs should point back
//zz                                       at their owner thread. */
//zz    *new_segP = mk_Segment( thr, cur_seg, NULL/*other*/ );
//zz    *new_segidP = alloc_SegmentID();
//zz    map_segments_add( *new_segidP, *new_segP );
//zz    thr->csegid = *new_segidP;
//zz }


/* The lock at 'lock_ga' has acquired a writer.  Make all necessary
   updates, and also do all possible error checks. */
static 
void evhH__post_thread_w_acquires_lock ( Thread* thr, 
                                         LockKind lkk, Addr lock_ga )
{
   Lock* lk; 

   /* Basically what we need to do is call lockN_acquire_writer.
      However, that will barf if any 'invalid' lock states would
      result.  Therefore check before calling.  Side effect is that
      'HG_(is_sane_LockN)(lk)' is both a pre- and post-condition of this
      routine. 

      Because this routine is only called after successful lock
      acquisition, we should not be asked to move the lock into any
      invalid states.  Requests to do so are bugs in libpthread, since
      that should have rejected any such requests. */

   tl_assert(HG_(is_sane_Thread)(thr));
   /* Try to find the lock.  If we can't, then create a new one with
      kind 'lkk'. */
   lk = map_locks_lookup_or_create( 
           lkk, lock_ga, map_threads_reverse_lookup_SLOW(thr) );
   tl_assert( HG_(is_sane_LockN)(lk) );

   /* check libhb level entities exist */
   tl_assert(thr->hbthr);
   tl_assert(lk->hbso);

   if (lk->heldBy == NULL) {
      /* the lock isn't held.  Simple. */
      tl_assert(!lk->heldW);
      lockN_acquire_writer( lk, thr );
      /* acquire a dependency from the lock's VCs */
      libhb_so_recv( thr->hbthr, lk->hbso, True/*strong_recv*/ );
      goto noerror;
   }

   /* So the lock is already held.  If held as a r-lock then
      libpthread must be buggy. */
   tl_assert(lk->heldBy);
   if (!lk->heldW) {
      HG_(record_error_Misc)(
         thr, "Bug in libpthread: write lock "
              "granted on rwlock which is currently rd-held");
      goto error;
   }

   /* So the lock is held in w-mode.  If it's held by some other
      thread, then libpthread must be buggy. */
   tl_assert(VG_(sizeUniqueBag)(lk->heldBy) == 1); /* from precondition */

   if (thr != (Thread*)VG_(anyElementOfBag)(lk->heldBy)) {
      HG_(record_error_Misc)(
         thr, "Bug in libpthread: write lock "
              "granted on mutex/rwlock which is currently "
              "wr-held by a different thread");
      goto error;
   }

   /* So the lock is already held in w-mode by 'thr'.  That means this
      is an attempt to lock it recursively, which is only allowable
      for LK_mbRec kinded locks.  Since this routine is called only
      once the lock has been acquired, this must also be a libpthread
      bug. */
   if (lk->kind != LK_mbRec) {
      HG_(record_error_Misc)(
         thr, "Bug in libpthread: recursive write lock "
              "granted on mutex/wrlock which does not "
              "support recursion");
      goto error;
   }

   /* So we are recursively re-locking a lock we already w-hold. */
   lockN_acquire_writer( lk, thr );
   /* acquire a dependency from the lock's VC.  Probably pointless,
      but also harmless. */
   libhb_so_recv( thr->hbthr, lk->hbso, True/*strong_recv*/ );
   goto noerror;

  noerror:
   if (HG_(clo_track_lockorders)) {
      /* check lock order acquisition graph, and update.  This has to
         happen before the lock is added to the thread's locksetA/W. */
      laog__pre_thread_acquires_lock( thr, lk );
   }
   /* update the thread's held-locks set */
   thr->locksetA = HG_(addToWS)( univ_lsets, thr->locksetA, (UWord)lk );
   thr->locksetW = HG_(addToWS)( univ_lsets, thr->locksetW, (UWord)lk );
   /* fall through */

  error:
   tl_assert(HG_(is_sane_LockN)(lk));
}


/* The lock at 'lock_ga' has acquired a reader.  Make all necessary
   updates, and also do all possible error checks. */
static 
void evhH__post_thread_r_acquires_lock ( Thread* thr, 
                                         LockKind lkk, Addr lock_ga )
{
   Lock* lk; 

   /* Basically what we need to do is call lockN_acquire_reader.
      However, that will barf if any 'invalid' lock states would
      result.  Therefore check before calling.  Side effect is that
      'HG_(is_sane_LockN)(lk)' is both a pre- and post-condition of this
      routine. 

      Because this routine is only called after successful lock
      acquisition, we should not be asked to move the lock into any
      invalid states.  Requests to do so are bugs in libpthread, since
      that should have rejected any such requests. */

   tl_assert(HG_(is_sane_Thread)(thr));
   /* Try to find the lock.  If we can't, then create a new one with
      kind 'lkk'.  Only a reader-writer lock can be read-locked,
      hence the first assertion. */
   tl_assert(lkk == LK_rdwr);
   lk = map_locks_lookup_or_create( 
           lkk, lock_ga, map_threads_reverse_lookup_SLOW(thr) );
   tl_assert( HG_(is_sane_LockN)(lk) );

   /* check libhb level entities exist */
   tl_assert(thr->hbthr);
   tl_assert(lk->hbso);

   if (lk->heldBy == NULL) {
      /* the lock isn't held.  Simple. */
      tl_assert(!lk->heldW);
      lockN_acquire_reader( lk, thr );
      /* acquire a dependency from the lock's VC */
      libhb_so_recv( thr->hbthr, lk->hbso, False/*!strong_recv*/ );
      goto noerror;
   }

   /* So the lock is already held.  If held as a w-lock then
      libpthread must be buggy. */
   tl_assert(lk->heldBy);
   if (lk->heldW) {
      HG_(record_error_Misc)( thr, "Bug in libpthread: read lock "
                                   "granted on rwlock which is "
                                   "currently wr-held");
      goto error;
   }

   /* Easy enough.  In short anybody can get a read-lock on a rwlock
      provided it is either unlocked or already in rd-held. */
   lockN_acquire_reader( lk, thr );
   /* acquire a dependency from the lock's VC.  Probably pointless,
      but also harmless. */
   libhb_so_recv( thr->hbthr, lk->hbso, False/*!strong_recv*/ );
   goto noerror;

  noerror:
   if (HG_(clo_track_lockorders)) {
      /* check lock order acquisition graph, and update.  This has to
         happen before the lock is added to the thread's locksetA/W. */
      laog__pre_thread_acquires_lock( thr, lk );
   }
   /* update the thread's held-locks set */
   thr->locksetA = HG_(addToWS)( univ_lsets, thr->locksetA, (UWord)lk );
   /* but don't update thr->locksetW, since lk is only rd-held */
   /* fall through */

  error:
   tl_assert(HG_(is_sane_LockN)(lk));
}


/* The lock at 'lock_ga' is just about to be unlocked.  Make all
   necessary updates, and also do all possible error checks. */
static 
void evhH__pre_thread_releases_lock ( Thread* thr,
                                      Addr lock_ga, Bool isRDWR )
{
   Lock* lock;
   Word  n;
   Bool  was_heldW;

   /* This routine is called prior to a lock release, before
      libpthread has had a chance to validate the call.  Hence we need
      to detect and reject any attempts to move the lock into an
      invalid state.  Such attempts are bugs in the client.

      isRDWR is True if we know from the wrapper context that lock_ga
      should refer to a reader-writer lock, and is False if [ditto]
      lock_ga should refer to a standard mutex. */

   tl_assert(HG_(is_sane_Thread)(thr));
   lock = map_locks_maybe_lookup( lock_ga );

   if (!lock) {
      /* We know nothing about a lock at 'lock_ga'.  Nevertheless
         the client is trying to unlock it.  So complain, then ignore
         the attempt. */
      HG_(record_error_UnlockBogus)( thr, lock_ga );
      return;
   }

   tl_assert(lock->guestaddr == lock_ga);
   tl_assert(HG_(is_sane_LockN)(lock));

   if (isRDWR && lock->kind != LK_rdwr) {
      HG_(record_error_Misc)( thr, "pthread_rwlock_unlock with a "
                                   "pthread_mutex_t* argument " );
   }
   if ((!isRDWR) && lock->kind == LK_rdwr) {
      HG_(record_error_Misc)( thr, "pthread_mutex_unlock with a "
                                   "pthread_rwlock_t* argument " );
   }

   if (!lock->heldBy) {
      /* The lock is not held.  This indicates a serious bug in the
         client. */
      tl_assert(!lock->heldW);
      HG_(record_error_UnlockUnlocked)( thr, lock );
      tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetA, (UWord)lock ));
      tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetW, (UWord)lock ));
      goto error;
   }

   /* test just above dominates */
   tl_assert(lock->heldBy);
   was_heldW = lock->heldW;

   /* The lock is held.  Is this thread one of the holders?  If not,
      report a bug in the client. */
   n = VG_(elemBag)( lock->heldBy, (UWord)thr );
   tl_assert(n >= 0);
   if (n == 0) {
      /* We are not a current holder of the lock.  This is a bug in
         the guest, and (per POSIX pthread rules) the unlock
         attempt will fail.  So just complain and do nothing
         else. */
      Thread* realOwner = (Thread*)VG_(anyElementOfBag)( lock->heldBy );
      tl_assert(HG_(is_sane_Thread)(realOwner));
      tl_assert(realOwner != thr);
      tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetA, (UWord)lock ));
      tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetW, (UWord)lock ));
      HG_(record_error_UnlockForeign)( thr, realOwner, lock );
      goto error;
   }

   /* Ok, we hold the lock 'n' times. */
   tl_assert(n >= 1);

   lockN_release( lock, thr );

   n--;
   tl_assert(n >= 0);

   if (n > 0) {
      tl_assert(lock->heldBy);
      tl_assert(n == VG_(elemBag)( lock->heldBy, (UWord)thr )); 
      /* We still hold the lock.  So either it's a recursive lock 
         or a rwlock which is currently r-held. */
      tl_assert(lock->kind == LK_mbRec
                || (lock->kind == LK_rdwr && !lock->heldW));
      tl_assert(HG_(elemWS)( univ_lsets, thr->locksetA, (UWord)lock ));
      if (lock->heldW)
         tl_assert(HG_(elemWS)( univ_lsets, thr->locksetW, (UWord)lock ));
      else
         tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetW, (UWord)lock ));
   } else {
      /* n is zero.  This means we don't hold the lock any more.  But
         if it's a rwlock held in r-mode, someone else could still
         hold it.  Just do whatever sanity checks we can. */
      if (lock->kind == LK_rdwr && lock->heldBy) {
         /* It's a rwlock.  We no longer hold it but we used to;
            nevertheless it still appears to be held by someone else.
            The implication is that, prior to this release, it must
            have been shared by us and and whoever else is holding it;
            which in turn implies it must be r-held, since a lock
            can't be w-held by more than one thread. */
         /* The lock is now R-held by somebody else: */
         tl_assert(lock->heldW == False);
      } else {
         /* Normal case.  It's either not a rwlock, or it's a rwlock
            that we used to hold in w-mode (which is pretty much the
            same thing as a non-rwlock.)  Since this transaction is
            atomic (V does not allow multiple threads to run
            simultaneously), it must mean the lock is now not held by
            anybody.  Hence assert for it. */
         /* The lock is now not held by anybody: */
         tl_assert(!lock->heldBy);
         tl_assert(lock->heldW == False);
      }
      //if (lock->heldBy) {
      //   tl_assert(0 == VG_(elemBag)( lock->heldBy, (UWord)thr ));
      //}
      /* update this thread's lockset accordingly. */
      thr->locksetA
         = HG_(delFromWS)( univ_lsets, thr->locksetA, (UWord)lock );
      thr->locksetW
         = HG_(delFromWS)( univ_lsets, thr->locksetW, (UWord)lock );
      /* push our VC into the lock */
      tl_assert(thr->hbthr);
      tl_assert(lock->hbso);
      /* If the lock was previously W-held, then we want to do a
         strong send, and if previously R-held, then a weak send. */
      libhb_so_send( thr->hbthr, lock->hbso, was_heldW );
   }
   /* fall through */

  error:
   tl_assert(HG_(is_sane_LockN)(lock));
}


/* ---------------------------------------------------------- */
/* -------- Event handlers proper (evh__* functions) -------- */
/* ---------------------------------------------------------- */

/* What is the Thread* for the currently running thread?  This is
   absolutely performance critical.  We receive notifications from the
   core for client code starts/stops, and cache the looked-up result
   in 'current_Thread'.  Hence, for the vast majority of requests,
   finding the current thread reduces to a read of a global variable,
   provided get_current_Thread_in_C_C is inlined.

   Outside of client code, current_Thread is NULL, and presumably
   any uses of it will cause a segfault.  Hence:

   - for uses definitely within client code, use
     get_current_Thread_in_C_C.

   - for all other uses, use get_current_Thread.
*/

static Thread *current_Thread      = NULL,
              *current_Thread_prev = NULL;

static void evh__start_client_code ( ThreadId tid, ULong nDisp ) {
   if (0) VG_(printf)("start %d %llu\n", (Int)tid, nDisp);
   tl_assert(current_Thread == NULL);
   current_Thread = map_threads_lookup( tid );
   tl_assert(current_Thread != NULL);
   if (current_Thread != current_Thread_prev) {
      libhb_Thr_resumes( current_Thread->hbthr );
      current_Thread_prev = current_Thread;
   }
}
static void evh__stop_client_code ( ThreadId tid, ULong nDisp ) {
   if (0) VG_(printf)(" stop %d %llu\n", (Int)tid, nDisp);
   tl_assert(current_Thread != NULL);
   current_Thread = NULL;
   libhb_maybe_GC();
}
static inline Thread* get_current_Thread_in_C_C ( void ) {
   return current_Thread;
}
static inline Thread* get_current_Thread ( void ) {
   ThreadId coretid;
   Thread*  thr;
   thr = get_current_Thread_in_C_C();
   if (LIKELY(thr))
      return thr;
   /* evidently not in client code.  Do it the slow way. */
   coretid = VG_(get_running_tid)();
   /* FIXME: get rid of the following kludge.  It exists because
      evh__new_mem is called during initialisation (as notification
      of initial memory layout) and VG_(get_running_tid)() returns
      VG_INVALID_THREADID at that point. */
   if (coretid == VG_INVALID_THREADID)
      coretid = 1; /* KLUDGE */
   thr = map_threads_lookup( coretid );
   return thr;
}

static
void evh__new_mem ( Addr a, SizeT len ) {
   Thread *thr = get_current_Thread();
   if (SHOW_EVENTS >= 2)
      VG_(printf)("evh__new_mem(%p, %lu)\n", (void*)a, len );
   shadow_mem_make_New( thr, a, len );
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__new_mem-post");
   if (UNLIKELY(thr->pthread_create_nesting_level > 0))
      shadow_mem_make_Untracked( thr, a, len );
}

static
void evh__new_mem_stack ( Addr a, SizeT len ) {
   Thread *thr = get_current_Thread();
   if (SHOW_EVENTS >= 2)
      VG_(printf)("evh__new_mem_stack(%p, %lu)\n", (void*)a, len );
   shadow_mem_make_New( thr, -VG_STACK_REDZONE_SZB + a, len );
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__new_mem_stack-post");
   if (UNLIKELY(thr->pthread_create_nesting_level > 0))
      shadow_mem_make_Untracked( thr, a, len );
}

static
void evh__new_mem_w_tid ( Addr a, SizeT len, ThreadId tid ) {
   Thread *thr = get_current_Thread();
   if (SHOW_EVENTS >= 2)
      VG_(printf)("evh__new_mem_w_tid(%p, %lu)\n", (void*)a, len );
   shadow_mem_make_New( thr, a, len );
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__new_mem_w_tid-post");
   if (UNLIKELY(thr->pthread_create_nesting_level > 0))
      shadow_mem_make_Untracked( thr, a, len );
}

static
void evh__new_mem_w_perms ( Addr a, SizeT len, 
                            Bool rr, Bool ww, Bool xx, ULong di_handle ) {
   Thread *thr = get_current_Thread();
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__new_mem_w_perms(%p, %lu, %d,%d,%d)\n",
                  (void*)a, len, (Int)rr, (Int)ww, (Int)xx );
   if (rr || ww || xx) {
      shadow_mem_make_New( thr, a, len );
      if (UNLIKELY(thr->pthread_create_nesting_level > 0))
         shadow_mem_make_Untracked( thr, a, len );
   }
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__new_mem_w_perms-post");
}

static
void evh__set_perms ( Addr a, SizeT len,
                      Bool rr, Bool ww, Bool xx ) {
   // This handles mprotect requests.  If the memory is being put
   // into no-R no-W state, paint it as NoAccess, for the reasons
   // documented at evh__die_mem_munmap().
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__set_perms(%p, %lu, r=%d w=%d x=%d)\n",
                  (void*)a, len, (Int)rr, (Int)ww, (Int)xx );
   /* Hmm.  What should we do here, that actually makes any sense?
      Let's say: if neither readable nor writable, then declare it
      NoAccess, else leave it alone. */
   if (!(rr || ww))
      shadow_mem_make_NoAccess_AHAE( get_current_Thread(), a, len );
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__set_perms-post");
}

static
void evh__die_mem ( Addr a, SizeT len ) {
   // Urr, libhb ignores this.
   if (SHOW_EVENTS >= 2)
      VG_(printf)("evh__die_mem(%p, %lu)\n", (void*)a, len );
   shadow_mem_make_NoAccess_NoFX( get_current_Thread(), a, len );
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__die_mem-post");
}

static
void evh__die_mem_munmap ( Addr a, SizeT len ) {
   // It's important that libhb doesn't ignore this.  If, as is likely,
   // the client is subject to address space layout randomization,
   // then unmapped areas may never get remapped over, even in long
   // runs.  If we just ignore them we wind up with large resource
   // (VTS) leaks in libhb.  So force them to NoAccess, so that all
   // VTS references in the affected area are dropped.  Marking memory
   // as NoAccess is expensive, but we assume that munmap is sufficiently
   // rare that the space gains of doing this are worth the costs.
   if (SHOW_EVENTS >= 2)
      VG_(printf)("evh__die_mem_munmap(%p, %lu)\n", (void*)a, len );
   shadow_mem_make_NoAccess_AHAE( get_current_Thread(), a, len );
}

static
void evh__untrack_mem ( Addr a, SizeT len ) {
   // Libhb doesn't ignore this.
   if (SHOW_EVENTS >= 2)
      VG_(printf)("evh__untrack_mem(%p, %lu)\n", (void*)a, len );
   shadow_mem_make_Untracked( get_current_Thread(), a, len );
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__untrack_mem-post");
}

static
void evh__copy_mem ( Addr src, Addr dst, SizeT len ) {
   if (SHOW_EVENTS >= 2)
      VG_(printf)("evh__copy_mem(%p, %p, %lu)\n", (void*)src, (void*)dst, len );
   Thread *thr = get_current_Thread();
   if (LIKELY(thr->synchr_nesting == 0))
      shadow_mem_scopy_range( thr , src, dst, len );
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__copy_mem-post");
}

static
void evh__pre_thread_ll_create ( ThreadId parent, ThreadId child )
{
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__pre_thread_ll_create(p=%d, c=%d)\n",
                  (Int)parent, (Int)child );

   if (parent != VG_INVALID_THREADID) {
      Thread* thr_p;
      Thread* thr_c;
      Thr*    hbthr_p;
      Thr*    hbthr_c;

      tl_assert(HG_(is_sane_ThreadId)(parent));
      tl_assert(HG_(is_sane_ThreadId)(child));
      tl_assert(parent != child);

      thr_p = map_threads_maybe_lookup( parent );
      thr_c = map_threads_maybe_lookup( child );

      tl_assert(thr_p != NULL);
      tl_assert(thr_c == NULL);

      hbthr_p = thr_p->hbthr;
      tl_assert(hbthr_p != NULL);
      tl_assert( libhb_get_Thr_hgthread(hbthr_p) == thr_p );

      hbthr_c = libhb_create ( hbthr_p );

      /* Create a new thread record for the child. */
      /* a Thread for the new thread ... */
      thr_c = mk_Thread( hbthr_c );
      tl_assert( libhb_get_Thr_hgthread(hbthr_c) == NULL );
      libhb_set_Thr_hgthread(hbthr_c, thr_c);

      /* and bind it in the thread-map table */
      map_threads[child] = thr_c;
      tl_assert(thr_c->coretid == VG_INVALID_THREADID);
      thr_c->coretid = child;

      /* Record where the parent is so we can later refer to this in
         error messages.

         On x86/amd64-linux, this entails a nasty glibc specific hack.
         The stack snapshot is taken immediately after the parent has
         returned from its sys_clone call.  Unfortunately there is no
         unwind info for the insn following "syscall" - reading the
         glibc sources confirms this.  So we ask for a snapshot to be
         taken as if RIP was 3 bytes earlier, in a place where there
         is unwind info.  Sigh.
      */
      { Word first_ip_delta = 0;
#       if defined(VGP_amd64_linux) || defined(VGP_x86_linux)
        first_ip_delta = -3;
#       elif defined(VGP_arm64_linux) || defined(VGP_arm_linux)
        first_ip_delta = -1;
#       endif
        thr_c->created_at = VG_(record_ExeContext)(parent, first_ip_delta);
      }

      if (HG_(clo_ignore_thread_creation)) {
         HG_(thread_enter_pthread_create)(thr_c);
         tl_assert(thr_c->synchr_nesting == 0);
         HG_(thread_enter_synchr)(thr_c);
         /* Counterpart in _VG_USERREQ__HG_SET_MY_PTHREAD_T. */
      }
   }

   if (HG_(clo_sanity_flags) & SCE_THREADS)
      all__sanity_check("evh__pre_thread_create-post");
}

static
void evh__pre_thread_ll_exit ( ThreadId quit_tid )
{
   Int     nHeld;
   Thread* thr_q;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__pre_thread_ll_exit(thr=%d)\n",
                  (Int)quit_tid );

   /* quit_tid has disappeared without joining to any other thread.
      Therefore there is no synchronisation event associated with its
      exit and so we have to pretty much treat it as if it was still
      alive but mysteriously making no progress.  That is because, if
      we don't know when it really exited, then we can never say there
      is a point in time when we're sure the thread really has
      finished, and so we need to consider the possibility that it
      lingers indefinitely and continues to interact with other
      threads. */
   /* However, it might have rendezvous'd with a thread that called
      pthread_join with this one as arg, prior to this point (that's
      how NPTL works).  In which case there has already been a prior
      sync event.  So in any case, just let the thread exit.  On NPTL,
      all thread exits go through here. */
   tl_assert(HG_(is_sane_ThreadId)(quit_tid));
   thr_q = map_threads_maybe_lookup( quit_tid );
   tl_assert(thr_q != NULL);

   /* Complain if this thread holds any locks. */
   nHeld = HG_(cardinalityWS)( univ_lsets, thr_q->locksetA );
   tl_assert(nHeld >= 0);
   if (nHeld > 0) {
      HChar buf[80];
      VG_(sprintf)(buf, "Exiting thread still holds %d lock%s",
                        nHeld, nHeld > 1 ? "s" : "");
      HG_(record_error_Misc)( thr_q, buf );
   }

   /* Not much to do here:
      - tell libhb the thread is gone
      - clear the map_threads entry, in order that the Valgrind core
        can re-use it. */
   /* Cleanup actions (next 5 lines) copied in evh__atfork_child; keep
      in sync. */
   tl_assert(thr_q->hbthr);
   libhb_async_exit(thr_q->hbthr);
   tl_assert(thr_q->coretid == quit_tid);
   thr_q->coretid = VG_INVALID_THREADID;
   map_threads_delete( quit_tid );

   if (HG_(clo_sanity_flags) & SCE_THREADS)
      all__sanity_check("evh__pre_thread_ll_exit-post");
}

/* This is called immediately after fork, for the child only.  'tid'
   is the only surviving thread (as per POSIX rules on fork() in
   threaded programs), so we have to clean up map_threads to remove
   entries for any other threads. */
static
void evh__atfork_child ( ThreadId tid )
{
   UInt    i;
   Thread* thr;
   /* Slot 0 should never be used. */
   thr = map_threads_maybe_lookup( 0/*INVALID*/ );
   tl_assert(!thr);
   /* Clean up all other slots except 'tid'. */
   for (i = 1; i < VG_N_THREADS; i++) {
      if (i == tid)
         continue;
      thr = map_threads_maybe_lookup(i);
      if (!thr)
         continue;
      /* Cleanup actions (next 5 lines) copied from end of
         evh__pre_thread_ll_exit; keep in sync. */
      tl_assert(thr->hbthr);
      libhb_async_exit(thr->hbthr);
      tl_assert(thr->coretid == i);
      thr->coretid = VG_INVALID_THREADID;
      map_threads_delete(i);
   }
}

/* generate a dependence from the hbthr_q quitter to the hbthr_s stayer. */
static
void generate_quitter_stayer_dependence (Thr* hbthr_q, Thr* hbthr_s)
{
   SO*      so;
   /* Allocate a temporary synchronisation object and use it to send
      an imaginary message from the quitter to the stayer, the purpose
      being to generate a dependence from the quitter to the
      stayer. */
   so = libhb_so_alloc();
   tl_assert(so);
   /* Send last arg of _so_send as False, since the sending thread
      doesn't actually exist any more, so we don't want _so_send to
      try taking stack snapshots of it. */
   libhb_so_send(hbthr_q, so, True/*strong_send*//*?!? wrt comment above*/);
   libhb_so_recv(hbthr_s, so, True/*strong_recv*/);
   libhb_so_dealloc(so);

   /* Tell libhb that the quitter has been reaped.  Note that we might
      have to be cleverer about this, to exclude 2nd and subsequent
      notifications for the same hbthr_q, in the case where the app is
      buggy (calls pthread_join twice or more on the same thread) AND
      where libpthread is also buggy and doesn't return ESRCH on
      subsequent calls.  (If libpthread isn't thusly buggy, then the
      wrapper for pthread_join in hg_intercepts.c will stop us getting
      notified here multiple times for the same joinee.)  See also
      comments in helgrind/tests/jointwice.c. */
   libhb_joinedwith_done(hbthr_q);
}


static
void evh__HG_PTHREAD_JOIN_POST ( ThreadId stay_tid, Thread* quit_thr )
{
   Thread*  thr_s;
   Thread*  thr_q;
   Thr*     hbthr_s;
   Thr*     hbthr_q;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__post_thread_join(stayer=%d, quitter=%p)\n",
                  (Int)stay_tid, quit_thr );

   tl_assert(HG_(is_sane_ThreadId)(stay_tid));

   thr_s = map_threads_maybe_lookup( stay_tid );
   thr_q = quit_thr;
   tl_assert(thr_s != NULL);
   tl_assert(thr_q != NULL);
   tl_assert(thr_s != thr_q);

   hbthr_s = thr_s->hbthr;
   hbthr_q = thr_q->hbthr;
   tl_assert(hbthr_s != hbthr_q);
   tl_assert( libhb_get_Thr_hgthread(hbthr_s) == thr_s );
   tl_assert( libhb_get_Thr_hgthread(hbthr_q) == thr_q );

   generate_quitter_stayer_dependence (hbthr_q, hbthr_s);

   /* evh__pre_thread_ll_exit issues an error message if the exiting
      thread holds any locks.  No need to check here. */

   /* This holds because, at least when using NPTL as the thread
      library, we should be notified the low level thread exit before
      we hear of any join event on it.  The low level exit
      notification feeds through into evh__pre_thread_ll_exit,
      which should clear the map_threads entry for it.  Hence we
      expect there to be no map_threads entry at this point. */
   tl_assert( map_threads_maybe_reverse_lookup_SLOW(thr_q)
              == VG_INVALID_THREADID);

   if (HG_(clo_sanity_flags) & SCE_THREADS)
      all__sanity_check("evh__post_thread_join-post");
}

static
void evh__pre_mem_read ( CorePart part, ThreadId tid, const HChar* s, 
                         Addr a, SizeT size) {
   if (SHOW_EVENTS >= 2
       || (SHOW_EVENTS >= 1 && size != 1))
      VG_(printf)("evh__pre_mem_read(ctid=%d, \"%s\", %p, %lu)\n", 
                  (Int)tid, s, (void*)a, size );
   Thread *thr = map_threads_lookup(tid);
   if (LIKELY(thr->synchr_nesting == 0))
      shadow_mem_cread_range(thr, a, size);
   if (size >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__pre_mem_read-post");
}

static
void evh__pre_mem_read_asciiz ( CorePart part, ThreadId tid,
                                const HChar* s, Addr a ) {
   Int len;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__pre_mem_asciiz(ctid=%d, \"%s\", %p)\n", 
                  (Int)tid, s, (void*)a );
   // Don't segfault if the string starts in an obviously stupid
   // place.  Actually we should check the whole string, not just
   // the start address, but that's too much trouble.  At least
   // checking the first byte is better than nothing.  See #255009.
   if (!VG_(am_is_valid_for_client) (a, 1, VKI_PROT_READ))
      return;
   Thread *thr = map_threads_lookup(tid);
   len = VG_(strlen)( (HChar*) a );
   if (LIKELY(thr->synchr_nesting == 0))
      shadow_mem_cread_range( thr, a, len+1 );
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__pre_mem_read_asciiz-post");
}

static
void evh__pre_mem_write ( CorePart part, ThreadId tid, const HChar* s,
                          Addr a, SizeT size ) {
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__pre_mem_write(ctid=%d, \"%s\", %p, %lu)\n", 
                  (Int)tid, s, (void*)a, size );
   Thread *thr = map_threads_lookup(tid);
   if (LIKELY(thr->synchr_nesting == 0))
      shadow_mem_cwrite_range(thr, a, size);
   if (size >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__pre_mem_write-post");
}

static
void evh__new_mem_heap ( Addr a, SizeT len, Bool is_inited ) {
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__new_mem_heap(%p, %lu, inited=%d)\n", 
                  (void*)a, len, (Int)is_inited );
   // We ignore the initialisation state (is_inited); that's ok.
   shadow_mem_make_New(get_current_Thread(), a, len);
   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__pre_mem_read-post");
}

static
void evh__die_mem_heap ( Addr a, SizeT len ) {
   Thread* thr;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__die_mem_heap(%p, %lu)\n", (void*)a, len );
   thr = get_current_Thread();
   tl_assert(thr);
   if (HG_(clo_free_is_write)) {
      /* Treat frees as if the memory was written immediately prior to
         the free.  This shakes out more races, specifically, cases
         where memory is referenced by one thread, and freed by
         another, and there's no observable synchronisation event to
         guarantee that the reference happens before the free. */
      if (LIKELY(thr->synchr_nesting == 0))
         shadow_mem_cwrite_range(thr, a, len);
   }
   shadow_mem_make_NoAccess_AHAE( thr, a, len );
   /* We used to call instead
          shadow_mem_make_NoAccess_NoFX( thr, a, len );
      A non-buggy application will not access anymore
      the freed memory, and so marking no access is in theory useless.
      Not marking freed memory would avoid the overhead for applications
      doing mostly malloc/free, as the freed memory should then be recycled
      very quickly after marking.
      We rather mark it noaccess for the following reasons:
        * accessibility bits then always correctly represents the memory
          status (e.g. for the client request VALGRIND_HG_GET_ABITS).
        * the overhead is reasonable (about 5 seconds per Gb in 1000 bytes
          blocks, on a ppc64le, for a unrealistic workload of an application
          doing only malloc/free).
        * marking no access allows to GC the SecMap, which might improve
          performance and/or memory usage.
        * we might detect more applications bugs when memory is marked
          noaccess.
      If needed, we could support here an option --free-is-noaccess=yes|no
      to avoid marking freed memory as no access if some applications
      would need to avoid the marking noaccess overhead. */

   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
      all__sanity_check("evh__pre_mem_read-post");
}

/* --- Event handlers called from generated code --- */

static VG_REGPARM(1)
void evh__mem_help_cread_1(Addr a) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CREAD_1(hbthr, a);
}

static VG_REGPARM(1)
void evh__mem_help_cread_2(Addr a) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CREAD_2(hbthr, a);
}

static VG_REGPARM(1)
void evh__mem_help_cread_4(Addr a) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CREAD_4(hbthr, a);
}

static VG_REGPARM(1)
void evh__mem_help_cread_8(Addr a) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CREAD_8(hbthr, a);
}

static VG_REGPARM(2)
void evh__mem_help_cread_N(Addr a, SizeT size) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CREAD_N(hbthr, a, size);
}

static VG_REGPARM(1)
void evh__mem_help_cwrite_1(Addr a) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CWRITE_1(hbthr, a);
}

static VG_REGPARM(1)
void evh__mem_help_cwrite_2(Addr a) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CWRITE_2(hbthr, a);
}

static VG_REGPARM(1)
void evh__mem_help_cwrite_4(Addr a) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CWRITE_4(hbthr, a);
}

static VG_REGPARM(1)
void evh__mem_help_cwrite_8(Addr a) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CWRITE_8(hbthr, a);
}

static VG_REGPARM(2)
void evh__mem_help_cwrite_N(Addr a, SizeT size) {
   Thread*  thr = get_current_Thread_in_C_C();
   Thr*     hbthr = thr->hbthr;
   if (LIKELY(thr->synchr_nesting == 0))
      LIBHB_CWRITE_N(hbthr, a, size);
}


/* ------------------------------------------------------- */
/* -------------- events to do with mutexes -------------- */
/* ------------------------------------------------------- */

/* EXPOSITION only: by intercepting lock init events we can show the
   user where the lock was initialised, rather than only being able to
   show where it was first locked.  Intercepting lock initialisations
   is not necessary for the basic operation of the race checker. */
static
void evh__HG_PTHREAD_MUTEX_INIT_POST( ThreadId tid, 
                                      void* mutex, Word mbRec )
{
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_MUTEX_INIT_POST(ctid=%d, mbRec=%ld, %p)\n", 
                  (Int)tid, mbRec, (void*)mutex );
   tl_assert(mbRec == 0 || mbRec == 1);
   map_locks_lookup_or_create( mbRec ? LK_mbRec : LK_nonRec,
                               (Addr)mutex, tid );
   if (HG_(clo_sanity_flags) & SCE_LOCKS)
      all__sanity_check("evh__hg_PTHREAD_MUTEX_INIT_POST");
}

static
void evh__HG_PTHREAD_MUTEX_DESTROY_PRE( ThreadId tid, void* mutex,
                                        Bool mutex_is_init )
{
   Thread* thr;
   Lock*   lk;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_MUTEX_DESTROY_PRE"
                  "(ctid=%d, %p, isInit=%d)\n", 
                  (Int)tid, (void*)mutex, (Int)mutex_is_init );

   thr = map_threads_maybe_lookup( tid );
   /* cannot fail - Thread* must already exist */
   tl_assert( HG_(is_sane_Thread)(thr) );

   lk = map_locks_maybe_lookup( (Addr)mutex );

   if (lk == NULL && mutex_is_init) {
      /* We're destroying a mutex which we don't have any record of,
         and which appears to have the value PTHREAD_MUTEX_INITIALIZER.
         Assume it never got used, and so we don't need to do anything
         more. */
      goto out;
   }

   if (lk == NULL || (lk->kind != LK_nonRec && lk->kind != LK_mbRec)) {
      HG_(record_error_Misc)(
         thr, "pthread_mutex_destroy with invalid argument" );
   }

   if (lk) {
      tl_assert( HG_(is_sane_LockN)(lk) );
      tl_assert( lk->guestaddr == (Addr)mutex );
      if (lk->heldBy) {
         /* Basically act like we unlocked the lock */
         HG_(record_error_Misc)(
            thr, "pthread_mutex_destroy of a locked mutex" );
         /* remove lock from locksets of all owning threads */
         remove_Lock_from_locksets_of_all_owning_Threads( lk );
         VG_(deleteBag)( lk->heldBy );
         lk->heldBy = NULL;
         lk->heldW = False;
         lk->acquired_at = NULL;
      }
      tl_assert( !lk->heldBy );
      tl_assert( HG_(is_sane_LockN)(lk) );
      
      if (HG_(clo_track_lockorders))
         laog__handle_one_lock_deletion(lk);
      map_locks_delete( lk->guestaddr );
      del_LockN( lk );
   }

  out:
   if (HG_(clo_sanity_flags) & SCE_LOCKS)
      all__sanity_check("evh__hg_PTHREAD_MUTEX_DESTROY_PRE");
}

static void evh__HG_PTHREAD_MUTEX_LOCK_PRE ( ThreadId tid,
                                             void* mutex, Word isTryLock )
{
   /* Just check the mutex is sane; nothing else to do. */
   // 'mutex' may be invalid - not checked by wrapper
   Thread* thr;
   Lock*   lk;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_MUTEX_LOCK_PRE(ctid=%d, mutex=%p)\n", 
                  (Int)tid, (void*)mutex );

   tl_assert(isTryLock == 0 || isTryLock == 1);
   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   lk = map_locks_maybe_lookup( (Addr)mutex );

   if (lk && (lk->kind == LK_rdwr)) {
      HG_(record_error_Misc)( thr, "pthread_mutex_lock with a "
                                   "pthread_rwlock_t* argument " );
   }

   if ( lk 
        && isTryLock == 0
        && (lk->kind == LK_nonRec || lk->kind == LK_rdwr)
        && lk->heldBy
        && lk->heldW
        && VG_(elemBag)( lk->heldBy, (UWord)thr ) > 0 ) {
      /* uh, it's a non-recursive lock and we already w-hold it, and
         this is a real lock operation (not a speculative "tryLock"
         kind of thing).  Duh.  Deadlock coming up; but at least
         produce an error message. */
      const HChar* errstr = "Attempt to re-lock a "
                            "non-recursive lock I already hold";
      const HChar* auxstr = "Lock was previously acquired";
      if (lk->acquired_at) {
         HG_(record_error_Misc_w_aux)( thr, errstr, auxstr, lk->acquired_at );
      } else {
         HG_(record_error_Misc)( thr, errstr );
      }
   }
}

static void evh__HG_PTHREAD_MUTEX_LOCK_POST ( ThreadId tid, void* mutex )
{
   // only called if the real library call succeeded - so mutex is sane
   Thread* thr;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_MUTEX_LOCK_POST(ctid=%d, mutex=%p)\n", 
                  (Int)tid, (void*)mutex );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   evhH__post_thread_w_acquires_lock( 
      thr, 
      LK_mbRec, /* if not known, create new lock with this LockKind */
      (Addr)mutex
   );
}

static void evh__HG_PTHREAD_MUTEX_UNLOCK_PRE ( ThreadId tid, void* mutex )
{
   // 'mutex' may be invalid - not checked by wrapper
   Thread* thr;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_MUTEX_UNLOCK_PRE(ctid=%d, mutex=%p)\n", 
                  (Int)tid, (void*)mutex );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   evhH__pre_thread_releases_lock( thr, (Addr)mutex, False/*!isRDWR*/ );
}

static void evh__HG_PTHREAD_MUTEX_UNLOCK_POST ( ThreadId tid, void* mutex )
{
   // only called if the real library call succeeded - so mutex is sane
   Thread* thr;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_MUTEX_UNLOCK_POST(ctid=%d, mutex=%p)\n", 
                  (Int)tid, (void*)mutex );
   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   // anything we should do here?
}


/* ------------------------------------------------------- */
/* -------------- events to do with spinlocks ------------ */
/* ------------------------------------------------------- */

/* All a bit of a kludge.  Pretend we're really dealing with ordinary
   pthread_mutex_t's instead, for the most part. */

static void evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE( ThreadId tid, 
                                                     void* slock )
{
   Thread* thr;
   Lock*   lk;
   /* In glibc's kludgey world, we're either initialising or unlocking
      it.  Since this is the pre-routine, if it is locked, unlock it
      and take a dependence edge.  Otherwise, do nothing. */

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE"
                  "(ctid=%d, slock=%p)\n", 
                  (Int)tid, (void*)slock );

   thr = map_threads_maybe_lookup( tid );
   /* cannot fail - Thread* must already exist */;
   tl_assert( HG_(is_sane_Thread)(thr) );

   lk = map_locks_maybe_lookup( (Addr)slock );
   if (lk && lk->heldBy) {
      /* it's held.  So do the normal pre-unlock actions, as copied
         from evh__HG_PTHREAD_MUTEX_UNLOCK_PRE.  This stupidly
         duplicates the map_locks_maybe_lookup. */
      evhH__pre_thread_releases_lock( thr, (Addr)slock,
                                           False/*!isRDWR*/ );
   }
}

static void evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_POST( ThreadId tid, 
                                                      void* slock )
{
   Lock* lk;
   /* More kludgery.  If the lock has never been seen before, do
      actions as per evh__HG_PTHREAD_MUTEX_INIT_POST.  Else do
      nothing. */

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_SPIN_INIT_OR_UNLOCK_POST"
                  "(ctid=%d, slock=%p)\n", 
                  (Int)tid, (void*)slock );

   lk = map_locks_maybe_lookup( (Addr)slock );
   if (!lk) {
      map_locks_lookup_or_create( LK_nonRec, (Addr)slock, tid );
   }
}

static void evh__HG_PTHREAD_SPIN_LOCK_PRE( ThreadId tid, 
                                           void* slock, Word isTryLock )
{
   evh__HG_PTHREAD_MUTEX_LOCK_PRE( tid, slock, isTryLock );
}

static void evh__HG_PTHREAD_SPIN_LOCK_POST( ThreadId tid, 
                                            void* slock )
{
   evh__HG_PTHREAD_MUTEX_LOCK_POST( tid, slock );
}

static void evh__HG_PTHREAD_SPIN_DESTROY_PRE( ThreadId tid, 
                                              void* slock )
{
   evh__HG_PTHREAD_MUTEX_DESTROY_PRE( tid, slock, 0/*!isInit*/ );
}


/* ----------------------------------------------------- */
/* --------------- events to do with CVs --------------- */
/* ----------------------------------------------------- */

/* A mapping from CV to (the SO associated with it, plus some
   auxiliary data for error checking).  When the CV is
   signalled/broadcasted upon, we do a 'send' into the SO, and when a
   wait on it completes, we do a 'recv' from the SO.  This is believed
   to give the correct happens-before events arising from CV
   signallings/broadcasts.
*/

/* .so is the SO for this CV.
   .mx_ga is the associated mutex, when .nWaiters > 0

   POSIX says effectively that the first pthread_cond_{timed}wait call
   causes a dynamic binding between the CV and the mutex, and that
   lasts until such time as the waiter count falls to zero.  Hence
   need to keep track of the number of waiters in order to do
   consistency tracking. */
typedef
   struct { 
      SO*   so;       /* libhb-allocated SO */
      void* mx_ga;    /* addr of associated mutex, if any */
      UWord nWaiters; /* # threads waiting on the CV */
   }
   CVInfo;


/* pthread_cond_t* -> CVInfo* */
static WordFM* map_cond_to_CVInfo = NULL;

static void map_cond_to_CVInfo_INIT ( void ) {
   if (UNLIKELY(map_cond_to_CVInfo == NULL)) {
      map_cond_to_CVInfo = VG_(newFM)( HG_(zalloc),
                                       "hg.mctCI.1", HG_(free), NULL );
   }
}

static CVInfo* map_cond_to_CVInfo_lookup_or_alloc ( void* cond ) {
   UWord key, val;
   map_cond_to_CVInfo_INIT();
   if (VG_(lookupFM)( map_cond_to_CVInfo, &key, &val, (UWord)cond )) {
      tl_assert(key == (UWord)cond);
      return (CVInfo*)val;
   } else {
      SO*     so  = libhb_so_alloc();
      CVInfo* cvi = HG_(zalloc)("hg.mctCloa.1", sizeof(CVInfo));
      cvi->so     = so;
      cvi->mx_ga  = 0;
      VG_(addToFM)( map_cond_to_CVInfo, (UWord)cond, (UWord)cvi );
      return cvi;
   }
}

static CVInfo* map_cond_to_CVInfo_lookup_NO_alloc ( void* cond ) {
   UWord key, val;
   map_cond_to_CVInfo_INIT();
   if (VG_(lookupFM)( map_cond_to_CVInfo, &key, &val, (UWord)cond )) {
      tl_assert(key == (UWord)cond);
      return (CVInfo*)val;
   } else {
      return NULL;
   }
}

static void map_cond_to_CVInfo_delete ( ThreadId tid,
                                        void* cond, Bool cond_is_init ) {
   Thread*   thr;
   UWord keyW, valW;

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   map_cond_to_CVInfo_INIT();
   if (VG_(lookupFM)( map_cond_to_CVInfo, &keyW, &valW, (UWord)cond )) {
      CVInfo* cvi = (CVInfo*)valW;
      tl_assert(keyW == (UWord)cond);
      tl_assert(cvi);
      tl_assert(cvi->so);
      if (cvi->nWaiters > 0) {
         HG_(record_error_Misc)(
            thr, "pthread_cond_destroy:"
                 " destruction of condition variable being waited upon");
         /* Destroying a cond var being waited upon outcome is EBUSY and
            variable is not destroyed. */
         return;
      }
      if (!VG_(delFromFM)( map_cond_to_CVInfo, &keyW, &valW, (UWord)cond ))
         tl_assert(0); // cond var found above, and not here ???
      libhb_so_dealloc(cvi->so);
      cvi->mx_ga = 0;
      HG_(free)(cvi);
   } else {
      /* We have no record of this CV.  So complain about it
         .. except, don't bother to complain if it has exactly the
         value PTHREAD_COND_INITIALIZER, since it might be that the CV
         was initialised like that but never used. */
      if (!cond_is_init) {
         HG_(record_error_Misc)(
            thr, "pthread_cond_destroy: destruction of unknown cond var");
      }
   }
}

static void evh__HG_PTHREAD_COND_SIGNAL_PRE ( ThreadId tid, void* cond )
{
   /* 'tid' has signalled on 'cond'.  As per the comment above, bind
      cond to a SO if it is not already so bound, and 'send' on the
      SO.  This is later used by other thread(s) which successfully
      exit from a pthread_cond_wait on the same cv; then they 'recv'
      from the SO, thereby acquiring a dependency on this signalling
      event. */
   Thread*   thr;
   CVInfo*   cvi;
   //Lock*     lk;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_COND_SIGNAL_PRE(ctid=%d, cond=%p)\n", 
                  (Int)tid, (void*)cond );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   cvi = map_cond_to_CVInfo_lookup_or_alloc( cond );
   tl_assert(cvi);
   tl_assert(cvi->so);

   // error-if: mutex is bogus
   // error-if: mutex is not locked
   // Hmm.  POSIX doesn't actually say that it's an error to call 
   // pthread_cond_signal with the associated mutex being unlocked.
   // Although it does say that it should be "if consistent scheduling
   // is desired."  For that reason, print "dubious" if the lock isn't
   // held by any thread.  Skip the "dubious" if it is held by some
   // other thread; that sounds straight-out wrong.
   //
   // Anybody who writes code that signals on a CV without holding
   // the associated MX needs to be shipped off to a lunatic asylum
   // ASAP, even though POSIX doesn't actually declare such behaviour
   // illegal -- it makes code extremely difficult to understand/
   // reason about.  In particular it puts the signalling thread in
   // a situation where it is racing against the released waiter
   // as soon as the signalling is done, and so there needs to be
   // some auxiliary synchronisation mechanism in the program that
   // makes this safe -- or the race(s) need to be harmless, or
   // probably nonexistent.
   //
   if (1) {
      Lock* lk = NULL;
      if (cvi->mx_ga != 0) {
         lk = map_locks_maybe_lookup( (Addr)cvi->mx_ga );
      }
      /* note: lk could be NULL.  Be careful. */
      if (lk) {
         if (lk->kind == LK_rdwr) {
            HG_(record_error_Misc)(thr,
               "pthread_cond_{signal,broadcast}: associated lock is a rwlock");
         }
         if (lk->heldBy == NULL) {
            HG_(record_error_Misc)(thr,
               "pthread_cond_{signal,broadcast}: dubious: "
               "associated lock is not held by any thread");
         }
         if (lk->heldBy != NULL && 0 == VG_(elemBag)(lk->heldBy, (UWord)thr)) {
            HG_(record_error_Misc)(thr,
               "pthread_cond_{signal,broadcast}: "
               "associated lock is not held by calling thread");
         }
      } else {
         /* Couldn't even find the damn thing. */
         // But actually .. that's not necessarily an error.  We don't
         // know the (CV,MX) binding until a pthread_cond_wait or bcast
         // shows us what it is, and if that may not have happened yet.
         // So just keep quiet in this circumstance.
         //HG_(record_error_Misc)( thr, 
         //   "pthread_cond_{signal,broadcast}: "
         //   "no or invalid mutex associated with cond");
      }
   }

   libhb_so_send( thr->hbthr, cvi->so, True/*strong_send*/ );
}

/* returns True if it reckons 'mutex' is valid and held by this
   thread, else False */
static Bool evh__HG_PTHREAD_COND_WAIT_PRE ( ThreadId tid,
                                            void* cond, void* mutex )
{
   Thread* thr;
   Lock*   lk;
   Bool    lk_valid = True;
   CVInfo* cvi;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_COND_WAIT_PRE"
                  "(ctid=%d, cond=%p, mutex=%p)\n", 
                  (Int)tid, (void*)cond, (void*)mutex );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   lk = map_locks_maybe_lookup( (Addr)mutex );

   /* Check for stupid mutex arguments.  There are various ways to be
      a bozo.  Only complain once, though, even if more than one thing
      is wrong. */
   if (lk == NULL) {
      lk_valid = False;
      HG_(record_error_Misc)( 
         thr, 
         "pthread_cond_{timed}wait called with invalid mutex" );
   } else {
      tl_assert( HG_(is_sane_LockN)(lk) );
      if (lk->kind == LK_rdwr) {
         lk_valid = False;
         HG_(record_error_Misc)(
            thr, "pthread_cond_{timed}wait called with mutex "
                 "of type pthread_rwlock_t*" );
      } else
         if (lk->heldBy == NULL) {
         lk_valid = False;
         HG_(record_error_Misc)( 
            thr, "pthread_cond_{timed}wait called with un-held mutex");
      } else
      if (lk->heldBy != NULL
          && VG_(elemBag)( lk->heldBy, (UWord)thr ) == 0) {
         lk_valid = False;
         HG_(record_error_Misc)(
            thr, "pthread_cond_{timed}wait called with mutex "
                 "held by a different thread" );
      }
   }

   // error-if: cond is also associated with a different mutex
   cvi = map_cond_to_CVInfo_lookup_or_alloc(cond);
   tl_assert(cvi);
   tl_assert(cvi->so);
   if (cvi->nWaiters == 0) {
      /* form initial (CV,MX) binding */
      cvi->mx_ga = mutex;
   }
   else /* check existing (CV,MX) binding */
   if (cvi->mx_ga != mutex) {
      HG_(record_error_Misc)(
         thr, "pthread_cond_{timed}wait: cond is associated "
              "with a different mutex");
   }
   cvi->nWaiters++;

   return lk_valid;
}

static void evh__HG_PTHREAD_COND_WAIT_POST ( ThreadId tid,
                                             void* cond, void* mutex,
                                             Bool timeout)
{
   /* A pthread_cond_wait(cond, mutex) completed successfully.  Find
      the SO for this cond, and 'recv' from it so as to acquire a
      dependency edge back to the signaller/broadcaster. */
   Thread* thr;
   CVInfo* cvi;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_COND_WAIT_POST"
                  "(ctid=%d, cond=%p, mutex=%p)\n, timeout=%d",
                  (Int)tid, (void*)cond, (void*)mutex, (Int)timeout );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   // error-if: cond is also associated with a different mutex

   cvi = map_cond_to_CVInfo_lookup_NO_alloc( cond );
   if (!cvi) {
      /* This could be either a bug in helgrind or the guest application
         that did an error (e.g. cond var was destroyed by another thread.
         Let's assume helgrind is perfect ...
         Note that this is similar to drd behaviour. */
      HG_(record_error_Misc)(thr, "condition variable has been destroyed while"
                             " being waited upon");
      return;
   }

   tl_assert(cvi);
   tl_assert(cvi->so);
   tl_assert(cvi->nWaiters > 0);

   if (!timeout && !libhb_so_everSent(cvi->so)) {
      /* Hmm.  How can a wait on 'cond' succeed if nobody signalled
         it?  If this happened it would surely be a bug in the threads
         library.  Or one of those fabled "spurious wakeups". */
      HG_(record_error_Misc)( thr, "Bug in libpthread: pthread_cond_wait "
                                   "succeeded"
                                   " without prior pthread_cond_post");
   }

   /* anyway, acquire a dependency on it. */
   libhb_so_recv( thr->hbthr, cvi->so, True/*strong_recv*/ );

   cvi->nWaiters--;
}

static void evh__HG_PTHREAD_COND_INIT_POST ( ThreadId tid,
                                             void* cond, void* cond_attr )
{
   CVInfo* cvi;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_COND_INIT_POST"
                  "(ctid=%d, cond=%p, cond_attr=%p)\n", 
                  (Int)tid, (void*)cond, (void*) cond_attr );

   cvi = map_cond_to_CVInfo_lookup_or_alloc( cond );
   tl_assert (cvi);
   tl_assert (cvi->so);
}


static void evh__HG_PTHREAD_COND_DESTROY_PRE ( ThreadId tid,
                                               void* cond, Bool cond_is_init )
{
   /* Deal with destroy events.  The only purpose is to free storage
      associated with the CV, so as to avoid any possible resource
      leaks. */
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_COND_DESTROY_PRE"
                  "(ctid=%d, cond=%p, cond_is_init=%d)\n", 
                  (Int)tid, (void*)cond, (Int)cond_is_init );

   map_cond_to_CVInfo_delete( tid, cond, cond_is_init );
}


/* ------------------------------------------------------- */
/* -------------- events to do with rwlocks -------------- */
/* ------------------------------------------------------- */

/* EXPOSITION only */
static
void evh__HG_PTHREAD_RWLOCK_INIT_POST( ThreadId tid, void* rwl )
{
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_RWLOCK_INIT_POST(ctid=%d, %p)\n", 
                  (Int)tid, (void*)rwl );
   map_locks_lookup_or_create( LK_rdwr, (Addr)rwl, tid );
   if (HG_(clo_sanity_flags) & SCE_LOCKS)
      all__sanity_check("evh__hg_PTHREAD_RWLOCK_INIT_POST");
}

static
void evh__HG_PTHREAD_RWLOCK_DESTROY_PRE( ThreadId tid, void* rwl )
{
   Thread* thr;
   Lock*   lk;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_RWLOCK_DESTROY_PRE(ctid=%d, %p)\n", 
                  (Int)tid, (void*)rwl );

   thr = map_threads_maybe_lookup( tid );
   /* cannot fail - Thread* must already exist */
   tl_assert( HG_(is_sane_Thread)(thr) );

   lk = map_locks_maybe_lookup( (Addr)rwl );

   if (lk == NULL || lk->kind != LK_rdwr) {
      HG_(record_error_Misc)(
         thr, "pthread_rwlock_destroy with invalid argument" );
   }

   if (lk) {
      tl_assert( HG_(is_sane_LockN)(lk) );
      tl_assert( lk->guestaddr == (Addr)rwl );
      if (lk->heldBy) {
         /* Basically act like we unlocked the lock */
         HG_(record_error_Misc)(
            thr, "pthread_rwlock_destroy of a locked mutex" );
         /* remove lock from locksets of all owning threads */
         remove_Lock_from_locksets_of_all_owning_Threads( lk );
         VG_(deleteBag)( lk->heldBy );
         lk->heldBy = NULL;
         lk->heldW = False;
         lk->acquired_at = NULL;
      }
      tl_assert( !lk->heldBy );
      tl_assert( HG_(is_sane_LockN)(lk) );
      
      if (HG_(clo_track_lockorders))
         laog__handle_one_lock_deletion(lk);
      map_locks_delete( lk->guestaddr );
      del_LockN( lk );
   }

   if (HG_(clo_sanity_flags) & SCE_LOCKS)
      all__sanity_check("evh__hg_PTHREAD_RWLOCK_DESTROY_PRE");
}

static 
void evh__HG_PTHREAD_RWLOCK_LOCK_PRE ( ThreadId tid,
                                       void* rwl,
                                       Word isW, Word isTryLock )
{
   /* Just check the rwl is sane; nothing else to do. */
   // 'rwl' may be invalid - not checked by wrapper
   Thread* thr;
   Lock*   lk;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_RWLOCK_LOCK_PRE(ctid=%d, isW=%d, %p)\n", 
                  (Int)tid, (Int)isW, (void*)rwl );

   tl_assert(isW == 0 || isW == 1); /* assured us by wrapper */
   tl_assert(isTryLock == 0 || isTryLock == 1); /* assured us by wrapper */
   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   lk = map_locks_maybe_lookup( (Addr)rwl );
   if ( lk 
        && (lk->kind == LK_nonRec || lk->kind == LK_mbRec) ) {
      /* Wrong kind of lock.  Duh.  */
      HG_(record_error_Misc)( 
         thr, "pthread_rwlock_{rd,rw}lock with a "
              "pthread_mutex_t* argument " );
   }
}

static 
void evh__HG_PTHREAD_RWLOCK_LOCK_POST ( ThreadId tid, void* rwl, Word isW )
{
   // only called if the real library call succeeded - so mutex is sane
   Thread* thr;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_RWLOCK_LOCK_POST(ctid=%d, isW=%d, %p)\n", 
                  (Int)tid, (Int)isW, (void*)rwl );

   tl_assert(isW == 0 || isW == 1); /* assured us by wrapper */
   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   (isW ? evhH__post_thread_w_acquires_lock 
        : evhH__post_thread_r_acquires_lock)( 
      thr, 
      LK_rdwr, /* if not known, create new lock with this LockKind */
      (Addr)rwl
   );
}

static void evh__HG_PTHREAD_RWLOCK_UNLOCK_PRE ( ThreadId tid, void* rwl )
{
   // 'rwl' may be invalid - not checked by wrapper
   Thread* thr;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_RWLOCK_UNLOCK_PRE(ctid=%d, rwl=%p)\n", 
                  (Int)tid, (void*)rwl );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   evhH__pre_thread_releases_lock( thr, (Addr)rwl, True/*isRDWR*/ );
}

static void evh__HG_PTHREAD_RWLOCK_UNLOCK_POST ( ThreadId tid, void* rwl )
{
   // only called if the real library call succeeded - so mutex is sane
   Thread* thr;
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__hg_PTHREAD_RWLOCK_UNLOCK_POST(ctid=%d, rwl=%p)\n", 
                  (Int)tid, (void*)rwl );
   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   // anything we should do here?
}


/* ---------------------------------------------------------- */
/* -------------- events to do with semaphores -------------- */
/* ---------------------------------------------------------- */

/* This is similar to but not identical to the handling for condition
   variables. */

/* For each semaphore, we maintain a stack of SOs.  When a 'post'
   operation is done on a semaphore (unlocking, essentially), a new SO
   is created for the posting thread, the posting thread does a strong
   send to it (which merely installs the posting thread's VC in the
   SO), and the SO is pushed on the semaphore's stack.

   Later, when a (probably different) thread completes 'wait' on the
   semaphore, we pop a SO off the semaphore's stack (which should be
   nonempty), and do a strong recv from it.  This mechanism creates
   dependencies between posters and waiters of the semaphore.

   It may not be necessary to use a stack - perhaps a bag of SOs would
   do.  But we do need to keep track of how many unused-up posts have
   happened for the semaphore.

   Imagine T1 and T2 both post once on a semaphore S, and T3 waits
   twice on S.  T3 cannot complete its waits without both T1 and T2
   posting.  The above mechanism will ensure that T3 acquires
   dependencies on both T1 and T2.

   When a semaphore is initialised with value N, we do as if we'd
   posted N times on the semaphore: basically create N SOs and do a
   strong send to all of then.  This allows up to N waits on the
   semaphore to acquire a dependency on the initialisation point,
   which AFAICS is the correct behaviour.

   We don't emit an error for DESTROY_PRE on a semaphore we don't know
   about.  We should.
*/

/* sem_t* -> XArray* SO* */
static WordFM* map_sem_to_SO_stack = NULL;

static void map_sem_to_SO_stack_INIT ( void ) {
   if (map_sem_to_SO_stack == NULL) {
      map_sem_to_SO_stack = VG_(newFM)( HG_(zalloc), "hg.mstSs.1",
                                        HG_(free), NULL );
   }
}

static void push_SO_for_sem ( void* sem, SO* so ) {
   UWord   keyW;
   XArray* xa;
   tl_assert(so);
   map_sem_to_SO_stack_INIT();
   if (VG_(lookupFM)( map_sem_to_SO_stack, 
                      &keyW, (UWord*)&xa, (UWord)sem )) {
      tl_assert(keyW == (UWord)sem);
      tl_assert(xa);
      VG_(addToXA)( xa, &so );
   } else {
     xa = VG_(newXA)( HG_(zalloc), "hg.pSfs.1", HG_(free), sizeof(SO*) );
      VG_(addToXA)( xa, &so );
      VG_(addToFM)( map_sem_to_SO_stack, (UWord)sem, (UWord)xa );
   }
}

static SO* mb_pop_SO_for_sem ( void* sem ) {
   UWord    keyW;
   XArray*  xa;
   SO* so;
   map_sem_to_SO_stack_INIT();
   if (VG_(lookupFM)( map_sem_to_SO_stack, 
                      &keyW, (UWord*)&xa, (UWord)sem )) {
      /* xa is the stack for this semaphore. */
      Word sz; 
      tl_assert(keyW == (UWord)sem);
      sz = VG_(sizeXA)( xa );
      tl_assert(sz >= 0);
      if (sz == 0)
         return NULL; /* odd, the stack is empty */
      so = *(SO**)VG_(indexXA)( xa, sz-1 );
      tl_assert(so);
      VG_(dropTailXA)( xa, 1 );
      return so;
   } else {
      /* hmm, that's odd.  No stack for this semaphore. */
      return NULL;
   }
}

static void evh__HG_POSIX_SEM_DESTROY_PRE ( ThreadId tid, void* sem )
{
   UWord keyW, valW;
   SO*   so;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_POSIX_SEM_DESTROY_PRE(ctid=%d, sem=%p)\n", 
                  (Int)tid, (void*)sem );

   map_sem_to_SO_stack_INIT();

   /* Empty out the semaphore's SO stack.  This way of doing it is
      stupid, but at least it's easy. */
   while (1) {
      so = mb_pop_SO_for_sem( sem );
      if (!so) break;
      libhb_so_dealloc(so);
   }

   if (VG_(delFromFM)( map_sem_to_SO_stack, &keyW, &valW, (UWord)sem )) {
      XArray* xa = (XArray*)valW;
      tl_assert(keyW == (UWord)sem);
      tl_assert(xa);
      tl_assert(VG_(sizeXA)(xa) == 0); /* preceding loop just emptied it */
      VG_(deleteXA)(xa);
   }
}

static 
void evh__HG_POSIX_SEM_INIT_POST ( ThreadId tid, void* sem, UWord value )
{
   SO*     so;
   Thread* thr;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_POSIX_SEM_INIT_POST(ctid=%d, sem=%p, value=%lu)\n", 
                  (Int)tid, (void*)sem, value );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   /* Empty out the semaphore's SO stack.  This way of doing it is
      stupid, but at least it's easy. */
   while (1) {
      so = mb_pop_SO_for_sem( sem );
      if (!so) break;
      libhb_so_dealloc(so);
   }

   /* If we don't do this check, the following while loop runs us out
      of memory for stupid initial values of 'value'. */
   if (value > 10000) {
      HG_(record_error_Misc)(
         thr, "sem_init: initial value exceeds 10000; using 10000" );
      value = 10000;
   }

   /* Now create 'valid' new SOs for the thread, do a strong send to
      each of them, and push them all on the stack. */
   for (; value > 0; value--) {
      Thr* hbthr = thr->hbthr;
      tl_assert(hbthr);

      so = libhb_so_alloc();
      libhb_so_send( hbthr, so, True/*strong send*/ );
      push_SO_for_sem( sem, so );
   }
}

static void evh__HG_POSIX_SEM_POST_PRE ( ThreadId tid, void* sem )
{
   /* 'tid' has posted on 'sem'.  Create a new SO, do a strong send to
      it (iow, write our VC into it, then tick ours), and push the SO
      on on a stack of SOs associated with 'sem'.  This is later used
      by other thread(s) which successfully exit from a sem_wait on
      the same sem; by doing a strong recv from SOs popped of the
      stack, they acquire dependencies on the posting thread
      segment(s). */

   Thread* thr;
   SO*     so;
   Thr*    hbthr;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_POSIX_SEM_POST_PRE(ctid=%d, sem=%p)\n", 
                  (Int)tid, (void*)sem );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   // error-if: sem is bogus

   hbthr = thr->hbthr;
   tl_assert(hbthr);

   so = libhb_so_alloc();
   libhb_so_send( hbthr, so, True/*strong send*/ );
   push_SO_for_sem( sem, so );
}

static void evh__HG_POSIX_SEM_WAIT_POST ( ThreadId tid, void* sem )
{
   /* A sem_wait(sem) completed successfully.  Pop the posting-SO for
      the 'sem' from this semaphore's SO-stack, and do a strong recv
      from it.  This creates a dependency back to one of the post-ers
      for the semaphore. */

   Thread* thr;
   SO*     so;
   Thr*    hbthr;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_POSIX_SEM_WAIT_POST(ctid=%d, sem=%p)\n", 
                  (Int)tid, (void*)sem );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   // error-if: sem is bogus

   so = mb_pop_SO_for_sem( sem );

   if (so) {
      hbthr = thr->hbthr;
      tl_assert(hbthr);

      libhb_so_recv( hbthr, so, True/*strong recv*/ );
      libhb_so_dealloc(so);
   } else {
      /* Hmm.  How can a wait on 'sem' succeed if nobody posted to it?
         If this happened it would surely be a bug in the threads
         library. */
      HG_(record_error_Misc)(
         thr, "Bug in libpthread: sem_wait succeeded on"
              " semaphore without prior sem_post");
   }
}


/* -------------------------------------------------------- */
/* -------------- events to do with barriers -------------- */
/* -------------------------------------------------------- */

typedef
   struct {
      Bool    initted; /* has it yet been initted by guest? */
      Bool    resizable; /* is resizing allowed? */
      UWord   size;    /* declared size */
      XArray* waiting; /* XA of Thread*.  # present is 0 .. .size */
   }
   Bar;

static Bar* new_Bar ( void ) {
   Bar* bar = HG_(zalloc)( "hg.nB.1 (new_Bar)", sizeof(Bar) );
   /* all fields are zero */
   tl_assert(bar->initted == False);
   return bar;
}

static void delete_Bar ( Bar* bar ) {
   tl_assert(bar);
   if (bar->waiting)
      VG_(deleteXA)(bar->waiting);
   HG_(free)(bar);
}

/* A mapping which stores auxiliary data for barriers. */

/* pthread_barrier_t* -> Bar* */
static WordFM* map_barrier_to_Bar = NULL;

static void map_barrier_to_Bar_INIT ( void ) {
   if (UNLIKELY(map_barrier_to_Bar == NULL)) {
      map_barrier_to_Bar = VG_(newFM)( HG_(zalloc),
                                       "hg.mbtBI.1", HG_(free), NULL );
   }
}

static Bar* map_barrier_to_Bar_lookup_or_alloc ( void* barrier ) {
   UWord key, val;
   map_barrier_to_Bar_INIT();
   if (VG_(lookupFM)( map_barrier_to_Bar, &key, &val, (UWord)barrier )) {
      tl_assert(key == (UWord)barrier);
      return (Bar*)val;
   } else {
      Bar* bar = new_Bar();
      VG_(addToFM)( map_barrier_to_Bar, (UWord)barrier, (UWord)bar );
      return bar;
   }
}

static void map_barrier_to_Bar_delete ( void* barrier ) {
   UWord keyW, valW;
   map_barrier_to_Bar_INIT();
   if (VG_(delFromFM)( map_barrier_to_Bar, &keyW, &valW, (UWord)barrier )) {
      Bar* bar = (Bar*)valW;
      tl_assert(keyW == (UWord)barrier);
      delete_Bar(bar);
   }
}


static void evh__HG_PTHREAD_BARRIER_INIT_PRE ( ThreadId tid,
                                               void* barrier,
                                               UWord count,
                                               UWord resizable )
{
   Thread* thr;
   Bar*    bar;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_BARRIER_INIT_PRE"
                  "(tid=%d, barrier=%p, count=%lu, resizable=%lu)\n", 
                  (Int)tid, (void*)barrier, count, resizable );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   if (count == 0) {
      HG_(record_error_Misc)(
         thr, "pthread_barrier_init: 'count' argument is zero"
      );
   }

   if (resizable != 0 && resizable != 1) {
      HG_(record_error_Misc)(
         thr, "pthread_barrier_init: invalid 'resizable' argument"
      );
   }

   bar = map_barrier_to_Bar_lookup_or_alloc(barrier);
   tl_assert(bar);

   if (bar->initted) {
      HG_(record_error_Misc)(
         thr, "pthread_barrier_init: barrier is already initialised"
      );
   }

   if (bar->waiting && VG_(sizeXA)(bar->waiting) > 0) {
      tl_assert(bar->initted);
      HG_(record_error_Misc)(
         thr, "pthread_barrier_init: threads are waiting at barrier"
      );
      VG_(dropTailXA)(bar->waiting, VG_(sizeXA)(bar->waiting));
   }
   if (!bar->waiting) {
      bar->waiting = VG_(newXA)( HG_(zalloc), "hg.eHPBIP.1", HG_(free),
                                 sizeof(Thread*) );
   }

   tl_assert(VG_(sizeXA)(bar->waiting) == 0);
   bar->initted   = True;
   bar->resizable = resizable == 1 ? True : False;
   bar->size      = count;
}


static void evh__HG_PTHREAD_BARRIER_DESTROY_PRE ( ThreadId tid,
                                                  void* barrier )
{
   Thread* thr;
   Bar*    bar;

   /* Deal with destroy events.  The only purpose is to free storage
      associated with the barrier, so as to avoid any possible
      resource leaks. */
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_BARRIER_DESTROY_PRE"
                  "(tid=%d, barrier=%p)\n", 
                  (Int)tid, (void*)barrier );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   bar = map_barrier_to_Bar_lookup_or_alloc(barrier);
   tl_assert(bar);

   if (!bar->initted) {
      HG_(record_error_Misc)(
         thr, "pthread_barrier_destroy: barrier was never initialised"
      );
   }

   if (bar->initted && bar->waiting && VG_(sizeXA)(bar->waiting) > 0) {
      HG_(record_error_Misc)(
         thr, "pthread_barrier_destroy: threads are waiting at barrier"
      );
   }

   /* Maybe we shouldn't do this; just let it persist, so that when it
      is reinitialised we don't need to do any dynamic memory
      allocation?  The downside is a potentially unlimited space leak,
      if the client creates (in turn) a large number of barriers all
      at different locations.  Note that if we do later move to the
      don't-delete-it scheme, we need to mark the barrier as
      uninitialised again since otherwise a later _init call will
      elicit a duplicate-init error.  */
   map_barrier_to_Bar_delete( barrier );
}


/* All the threads have arrived.  Now do the Interesting Bit.  Get a
   new synchronisation object and do a weak send to it from all the
   participating threads.  This makes its vector clocks be the join of
   all the individual threads' vector clocks.  Then do a strong
   receive from it back to all threads, so that their VCs are a copy
   of it (hence are all equal to the join of their original VCs.) */
static void do_barrier_cross_sync_and_empty ( Bar* bar )
{
   /* XXX check bar->waiting has no duplicates */
   UWord i;
   SO*   so = libhb_so_alloc();

   tl_assert(bar->waiting);
   tl_assert(VG_(sizeXA)(bar->waiting) == bar->size);

   /* compute the join ... */
   for (i = 0; i < bar->size; i++) {
      Thread* t = *(Thread**)VG_(indexXA)(bar->waiting, i);
      Thr* hbthr = t->hbthr;
      libhb_so_send( hbthr, so, False/*weak send*/ );
   }
   /* ... and distribute to all threads */
   for (i = 0; i < bar->size; i++) {
      Thread* t = *(Thread**)VG_(indexXA)(bar->waiting, i);
      Thr* hbthr = t->hbthr;
      libhb_so_recv( hbthr, so, True/*strong recv*/ );
   }

   /* finally, we must empty out the waiting vector */
   VG_(dropTailXA)(bar->waiting, VG_(sizeXA)(bar->waiting));

   /* and we don't need this any more.  Perhaps a stack-allocated
      SO would be better? */
   libhb_so_dealloc(so);
}


static void evh__HG_PTHREAD_BARRIER_WAIT_PRE ( ThreadId tid,
                                               void* barrier )
{
  /* This function gets called after a client thread calls
     pthread_barrier_wait but before it arrives at the real
     pthread_barrier_wait.

     Why is the following correct?  It's a bit subtle.

     If this is not the last thread arriving at the barrier, we simply
     note its presence and return.  Because valgrind (at least as of
     Nov 08) is single threaded, we are guaranteed safe from any race
     conditions when in this function -- no other client threads are
     running.

     If this is the last thread, then we are again the only running
     thread.  All the other threads will have either arrived at the
     real pthread_barrier_wait or are on their way to it, but in any
     case are guaranteed not to be able to move past it, because this
     thread is currently in this function and so has not yet arrived
     at the real pthread_barrier_wait.  That means that:

     1. While we are in this function, none of the other threads
        waiting at the barrier can move past it.

     2. When this function returns (and simulated execution resumes),
        this thread and all other waiting threads will be able to move
        past the real barrier.

     Because of this, it is now safe to update the vector clocks of
     all threads, to represent the fact that they all arrived at the
     barrier and have all moved on.  There is no danger of any
     complications to do with some threads leaving the barrier and
     racing back round to the front, whilst others are still leaving
     (which is the primary source of complication in correct handling/
     implementation of barriers).  That can't happen because we update
     here our data structures so as to indicate that the threads have
     passed the barrier, even though, as per (2) above, they are
     guaranteed not to pass the barrier until we return.

     This relies crucially on Valgrind being single threaded.  If that
     changes, this will need to be reconsidered.
   */
   Thread* thr;
   Bar*    bar;
   UWord   present;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_BARRIER_WAIT_PRE"
                  "(tid=%d, barrier=%p)\n", 
                  (Int)tid, (void*)barrier );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   bar = map_barrier_to_Bar_lookup_or_alloc(barrier);
   tl_assert(bar);

   if (!bar->initted) {
      HG_(record_error_Misc)(
         thr, "pthread_barrier_wait: barrier is uninitialised"
      );
      return; /* client is broken .. avoid assertions below */
   }

   /* guaranteed by _INIT_PRE above */
   tl_assert(bar->size > 0);
   tl_assert(bar->waiting);

   VG_(addToXA)( bar->waiting, &thr );

   /* guaranteed by this function */
   present = VG_(sizeXA)(bar->waiting);
   tl_assert(present > 0 && present <= bar->size);

   if (present < bar->size)
      return;

   do_barrier_cross_sync_and_empty(bar);
}


static void evh__HG_PTHREAD_BARRIER_RESIZE_PRE ( ThreadId tid,
                                                 void* barrier,
                                                 UWord newcount )
{
   Thread* thr;
   Bar*    bar;
   UWord   present;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_PTHREAD_BARRIER_RESIZE_PRE"
                  "(tid=%d, barrier=%p, newcount=%lu)\n", 
                  (Int)tid, (void*)barrier, newcount );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   bar = map_barrier_to_Bar_lookup_or_alloc(barrier);
   tl_assert(bar);

   if (!bar->initted) {
      HG_(record_error_Misc)(
         thr, "pthread_barrier_resize: barrier is uninitialised"
      );
      return; /* client is broken .. avoid assertions below */
   }

   if (!bar->resizable) {
      HG_(record_error_Misc)(
         thr, "pthread_barrier_resize: barrier is may not be resized"
      );
      return; /* client is broken .. avoid assertions below */
   }

   if (newcount == 0) {
      HG_(record_error_Misc)(
         thr, "pthread_barrier_resize: 'newcount' argument is zero"
      );
      return; /* client is broken .. avoid assertions below */
   }

   /* guaranteed by _INIT_PRE above */
   tl_assert(bar->size > 0);
   tl_assert(bar->waiting);
   /* Guaranteed by this fn */
   tl_assert(newcount > 0);

   if (newcount >= bar->size) {
      /* Increasing the capacity.  There's no possibility of threads
         moving on from the barrier in this situation, so just note
         the fact and do nothing more. */
      bar->size = newcount;
   } else {
      /* Decreasing the capacity.  If we decrease it to be equal or
         below the number of waiting threads, they will now move past
         the barrier, so need to mess with dep edges in the same way
         as if the barrier had filled up normally. */
      present = VG_(sizeXA)(bar->waiting);
      tl_assert(present >= 0 && present <= bar->size);
      if (newcount <= present) {
         bar->size = present; /* keep the cross_sync call happy */
         do_barrier_cross_sync_and_empty(bar);
      }
      bar->size = newcount;
   }
}


/* ----------------------------------------------------- */
/* ----- events to do with user-specified HB edges ----- */
/* ----------------------------------------------------- */

/* A mapping from arbitrary UWord tag to the SO associated with it.
   The UWord tags are meaningless to us, interpreted only by the
   user. */



/* UWord -> SO* */
static WordFM* map_usertag_to_SO = NULL;

static void map_usertag_to_SO_INIT ( void ) {
   if (UNLIKELY(map_usertag_to_SO == NULL)) {
      map_usertag_to_SO = VG_(newFM)( HG_(zalloc),
                                      "hg.mutS.1", HG_(free), NULL );
   }
}

static SO* map_usertag_to_SO_lookup_or_alloc ( UWord usertag ) {
   UWord key, val;
   map_usertag_to_SO_INIT();
   if (VG_(lookupFM)( map_usertag_to_SO, &key, &val, usertag )) {
      tl_assert(key == (UWord)usertag);
      return (SO*)val;
   } else {
      SO* so = libhb_so_alloc();
      VG_(addToFM)( map_usertag_to_SO, usertag, (UWord)so );
      return so;
   }
}

static void map_usertag_to_SO_delete ( UWord usertag ) {
   UWord keyW, valW;
   map_usertag_to_SO_INIT();
   if (VG_(delFromFM)( map_usertag_to_SO, &keyW, &valW, usertag )) {
      SO* so = (SO*)valW;
      tl_assert(keyW == usertag);
      tl_assert(so);
      libhb_so_dealloc(so);
   }
}


static
void evh__HG_USERSO_SEND_PRE ( ThreadId tid, UWord usertag )
{
   /* TID is just about to notionally sent a message on a notional
      abstract synchronisation object whose identity is given by
      USERTAG.  Bind USERTAG to a real SO if it is not already so
      bound, and do a 'weak send' on the SO.  This joins the vector
      clocks from this thread into any vector clocks already present
      in the SO.  The resulting SO vector clocks are later used by
      other thread(s) which successfully 'receive' from the SO,
      thereby acquiring a dependency on all the events that have
      previously signalled on this SO. */
   Thread* thr;
   SO*     so;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_USERSO_SEND_PRE(ctid=%d, usertag=%#lx)\n", 
                  (Int)tid, usertag );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   so = map_usertag_to_SO_lookup_or_alloc( usertag );
   tl_assert(so);

   libhb_so_send( thr->hbthr, so, False/*!strong_send*/ );
}

static
void evh__HG_USERSO_RECV_POST ( ThreadId tid, UWord usertag )
{
   /* TID has just notionally received a message from a notional
      abstract synchronisation object whose identity is given by
      USERTAG.  Bind USERTAG to a real SO if it is not already so
      bound.  If the SO has at some point in the past been 'sent' on,
      to a 'strong receive' on it, thereby acquiring a dependency on
      the sender. */
   Thread* thr;
   SO*     so;

   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_USERSO_RECV_POST(ctid=%d, usertag=%#lx)\n", 
                  (Int)tid, usertag );

   thr = map_threads_maybe_lookup( tid );
   tl_assert(thr); /* cannot fail - Thread* must already exist */

   so = map_usertag_to_SO_lookup_or_alloc( usertag );
   tl_assert(so);

   /* Acquire a dependency on it.  If the SO has never so far been
      sent on, then libhb_so_recv will do nothing.  So we're safe
      regardless of SO's history. */
   libhb_so_recv( thr->hbthr, so, True/*strong_recv*/ );
}

static
void evh__HG_USERSO_FORGET_ALL ( ThreadId tid, UWord usertag )
{
   /* TID declares that any happens-before edges notionally stored in
      USERTAG can be deleted.  If (as would normally be the case) a
      SO is associated with USERTAG, then the association is removed
      and all resources associated with SO are freed.  Importantly,
      that frees up any VTSs stored in SO. */
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_USERSO_FORGET_ALL(ctid=%d, usertag=%#lx)\n", 
                  (Int)tid, usertag );

   map_usertag_to_SO_delete( usertag );
}


#if defined(VGO_solaris)
/* ----------------------------------------------------- */
/* --- events to do with bind guard/clear intercepts --- */
/* ----------------------------------------------------- */

static
void evh__HG_RTLD_BIND_GUARD(ThreadId tid, Int flags)
{
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_RTLD_BIND_GUARD"
                  "(tid=%d, flags=%d)\n",
                  (Int)tid, flags);

   Thread *thr = map_threads_maybe_lookup(tid);
   tl_assert(thr != NULL);

   Int bindflag = (flags & VKI_THR_FLG_RTLD);
   if ((bindflag & thr->bind_guard_flag) == 0) {
      thr->bind_guard_flag |= bindflag;
      HG_(thread_enter_synchr)(thr);
      /* Misuse pthread_create_nesting_level for ignoring mutex activity. */
      HG_(thread_enter_pthread_create)(thr);
   }
}

static
void evh__HG_RTLD_BIND_CLEAR(ThreadId tid, Int flags)
{
   if (SHOW_EVENTS >= 1)
      VG_(printf)("evh__HG_RTLD_BIND_CLEAR"
                  "(tid=%d, flags=%d)\n",
                  (Int)tid, flags);

   Thread *thr = map_threads_maybe_lookup(tid);
   tl_assert(thr != NULL);

   Int bindflag = (flags & VKI_THR_FLG_RTLD);
   if ((thr->bind_guard_flag & bindflag) != 0) {
      thr->bind_guard_flag &= ~bindflag;
      HG_(thread_leave_synchr)(thr);
      HG_(thread_leave_pthread_create)(thr);
   }
}
#endif /* VGO_solaris */


/*--------------------------------------------------------------*/
/*--- Lock acquisition order monitoring                      ---*/
/*--------------------------------------------------------------*/

/* FIXME: here are some optimisations still to do in
          laog__pre_thread_acquires_lock.

   The graph is structured so that if L1 --*--> L2 then L1 must be
   acquired before L2.

   The common case is that some thread T holds (eg) L1 L2 and L3 and
   is repeatedly acquiring and releasing Ln, and there is no ordering
   error in what it is doing.  Hence it repeatly:

   (1) searches laog to see if Ln --*--> {L1,L2,L3}, which always 
       produces the answer No (because there is no error).

   (2) adds edges {L1,L2,L3} --> Ln to laog, which are already present
       (because they already got added the first time T acquired Ln).

   Hence cache these two events:

   (1) Cache result of the query from last time.  Invalidate the cache
       any time any edges are added to or deleted from laog.

   (2) Cache these add-edge requests and ignore them if said edges
       have already been added to laog.  Invalidate the cache any time
       any edges are deleted from laog.
*/

typedef
   struct {
      WordSetID inns; /* in univ_laog */
      WordSetID outs; /* in univ_laog */
   }
   LAOGLinks;

/* lock order acquisition graph */
static WordFM* laog = NULL; /* WordFM Lock* LAOGLinks* */

/* EXPOSITION ONLY: for each edge in 'laog', record the two places
   where that edge was created, so that we can show the user later if
   we need to. */
typedef
   struct {
      Addr        src_ga; /* Lock guest addresses for */
      Addr        dst_ga; /* src/dst of the edge */
      ExeContext* src_ec; /* And corresponding places where that */
      ExeContext* dst_ec; /* ordering was established */
   }
   LAOGLinkExposition;

static Word cmp_LAOGLinkExposition ( UWord llx1W, UWord llx2W ) {
   /* Compare LAOGLinkExposition*s by (src_ga,dst_ga) field pair. */
   LAOGLinkExposition* llx1 = (LAOGLinkExposition*)llx1W;
   LAOGLinkExposition* llx2 = (LAOGLinkExposition*)llx2W;
   if (llx1->src_ga < llx2->src_ga) return -1;
   if (llx1->src_ga > llx2->src_ga) return  1;
   if (llx1->dst_ga < llx2->dst_ga) return -1;
   if (llx1->dst_ga > llx2->dst_ga) return  1;
   return 0;
}

static WordFM* laog_exposition = NULL; /* WordFM LAOGLinkExposition* NULL */
/* end EXPOSITION ONLY */


__attribute__((noinline))
static void laog__init ( void )
{
   tl_assert(!laog);
   tl_assert(!laog_exposition);
   tl_assert(HG_(clo_track_lockorders));

   laog = VG_(newFM)( HG_(zalloc), "hg.laog__init.1", 
                      HG_(free), NULL/*unboxedcmp*/ );

   laog_exposition = VG_(newFM)( HG_(zalloc), "hg.laog__init.2", HG_(free), 
                                 cmp_LAOGLinkExposition );
}

static void laog__show ( const HChar* who ) {
   UWord i, ws_size;
   UWord* ws_words;
   Lock* me;
   LAOGLinks* links;
   VG_(printf)("laog (requested by %s) {\n", who);
   VG_(initIterFM)( laog );
   me = NULL;
   links = NULL;
   while (VG_(nextIterFM)( laog, (UWord*)&me,
                                 (UWord*)&links )) {
      tl_assert(me);
      tl_assert(links);
      VG_(printf)("   node %p:\n", me);
      HG_(getPayloadWS)( &ws_words, &ws_size, univ_laog, links->inns );
      for (i = 0; i < ws_size; i++)
         VG_(printf)("      inn %#lx\n", ws_words[i] );
      HG_(getPayloadWS)( &ws_words, &ws_size, univ_laog, links->outs );
      for (i = 0; i < ws_size; i++)
         VG_(printf)("      out %#lx\n", ws_words[i] );
      me = NULL;
      links = NULL;
   }
   VG_(doneIterFM)( laog );
   VG_(printf)("}\n");
}

static void univ_laog_do_GC ( void ) {
   Word i;
   LAOGLinks* links;
   Word seen = 0;
   Int prev_next_gc_univ_laog = next_gc_univ_laog;
   const UWord univ_laog_cardinality = HG_(cardinalityWSU)( univ_laog);

   Bool *univ_laog_seen = HG_(zalloc) ( "hg.gc_univ_laog.1",
                                        (Int) univ_laog_cardinality 
                                        * sizeof(Bool) );
   // univ_laog_seen[*] set to 0 (False) by zalloc.

   VG_(initIterFM)( laog );
   links = NULL;
   while (VG_(nextIterFM)( laog, NULL, (UWord*)&links )) {
      tl_assert(links);
      tl_assert(links->inns >= 0 && links->inns < univ_laog_cardinality);
      univ_laog_seen[links->inns] = True;
      tl_assert(links->outs >= 0 && links->outs < univ_laog_cardinality);
      univ_laog_seen[links->outs] = True;
      links = NULL;
   }
   VG_(doneIterFM)( laog );

   for (i = 0; i < (Int)univ_laog_cardinality; i++) {
      if (univ_laog_seen[i])
         seen++;
      else
         HG_(dieWS) ( univ_laog, (WordSet)i );
   }

   HG_(free) (univ_laog_seen);

   // We need to decide the value of the next_gc.
   // 3 solutions were looked at:
   // Sol 1: garbage collect at seen * 2
   //   This solution was a lot slower, probably because we both do a lot of
   //   garbage collection and do not keep long enough laog WV that will become
   //   useful  again very soon.
   // Sol 2: garbage collect at a percentage increase of the current cardinality
   //         (with a min increase of 1)
   //   Trials on a small test program with 1%, 5% and 10% increase was done.
   //   1% is slightly faster than 5%, which is slightly slower than 10%.
   //   However, on a big application, this caused the memory to be exhausted,
   //   as even a 1% increase of size at each gc becomes a lot, when many gc
   //   are done.
   // Sol 3: always garbage collect at current cardinality + 1.
   //   This solution was the fastest of the 3 solutions, and caused no memory
   //   exhaustion in the big application.
   // 
   // With regards to cost introduced by gc: on the t2t perf test (doing only
   // lock/unlock operations), t2t 50 10 2 was about 25% faster than the
   // version with garbage collection. With t2t 50 20 2, my machine started
   // to page out, and so the garbage collected version was much faster.
   // On smaller lock sets (e.g. t2t 20 5 2, giving about 100 locks), the
   // difference performance is insignificant (~ 0.1 s).
   // Of course, it might be that real life programs are not well represented
   // by t2t.
   
   // If ever we want to have a more sophisticated control
   // (e.g. clo options to control the percentage increase or fixed increased),
   // we should do it here, eg.
   //     next_gc_univ_laog = prev_next_gc_univ_laog + VG_(clo_laog_gc_fixed);
   // Currently, we just hard-code the solution 3 above.
   next_gc_univ_laog = prev_next_gc_univ_laog + 1;

   if (VG_(clo_stats))
      VG_(message)
         (Vg_DebugMsg,
          "univ_laog_do_GC cardinality entered %d exit %d next gc at %d\n",
          (Int)univ_laog_cardinality, (Int)seen, next_gc_univ_laog);
}


__attribute__((noinline))
static void laog__add_edge ( Lock* src, Lock* dst ) {
   UWord      keyW;
   LAOGLinks* links;
   Bool       presentF, presentR;
   if (0) VG_(printf)("laog__add_edge %p %p\n", src, dst);

   /* Take the opportunity to sanity check the graph.  Record in
      presentF if there is already a src->dst mapping in this node's
      forwards links, and presentR if there is already a src->dst
      mapping in this node's backwards links.  They should agree!
      Also, we need to know whether the edge was already present so as
      to decide whether or not to update the link details mapping.  We
      can compute presentF and presentR essentially for free, so may
      as well do this always. */
   presentF = presentR = False;

   /* Update the out edges for src */
   keyW  = 0;
   links = NULL;
   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)src )) {
      WordSetID outs_new;
      tl_assert(links);
      tl_assert(keyW == (UWord)src);
      outs_new = HG_(addToWS)( univ_laog, links->outs, (UWord)dst );
      presentF = outs_new == links->outs;
      links->outs = outs_new;
   } else {
      links = HG_(zalloc)("hg.lae.1", sizeof(LAOGLinks));
      links->inns = HG_(emptyWS)( univ_laog );
      links->outs = HG_(singletonWS)( univ_laog, (UWord)dst );
      VG_(addToFM)( laog, (UWord)src, (UWord)links );
   }
   /* Update the in edges for dst */
   keyW  = 0;
   links = NULL;
   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)dst )) {
      WordSetID inns_new;
      tl_assert(links);
      tl_assert(keyW == (UWord)dst);
      inns_new = HG_(addToWS)( univ_laog, links->inns, (UWord)src );
      presentR = inns_new == links->inns;
      links->inns = inns_new;
   } else {
      links = HG_(zalloc)("hg.lae.2", sizeof(LAOGLinks));
      links->inns = HG_(singletonWS)( univ_laog, (UWord)src );
      links->outs = HG_(emptyWS)( univ_laog );
      VG_(addToFM)( laog, (UWord)dst, (UWord)links );
   }

   tl_assert( (presentF && presentR) || (!presentF && !presentR) );

   if (!presentF && src->acquired_at && dst->acquired_at) {
      LAOGLinkExposition expo;
      /* If this edge is entering the graph, and we have acquired_at
         information for both src and dst, record those acquisition
         points.  Hence, if there is later a violation of this
         ordering, we can show the user the two places in which the
         required src-dst ordering was previously established. */
      if (0) VG_(printf)("acquire edge %#lx %#lx\n",
                         src->guestaddr, dst->guestaddr);
      expo.src_ga = src->guestaddr;
      expo.dst_ga = dst->guestaddr;
      expo.src_ec = NULL;
      expo.dst_ec = NULL;
      tl_assert(laog_exposition);
      if (VG_(lookupFM)( laog_exposition, NULL, NULL, (UWord)&expo )) {
         /* we already have it; do nothing */
      } else {
         LAOGLinkExposition* expo2 = HG_(zalloc)("hg.lae.3", 
                                               sizeof(LAOGLinkExposition));
         expo2->src_ga = src->guestaddr;
         expo2->dst_ga = dst->guestaddr;
         expo2->src_ec = src->acquired_at;
         expo2->dst_ec = dst->acquired_at;
         VG_(addToFM)( laog_exposition, (UWord)expo2, (UWord)NULL );
      }
   }

   if (HG_(cardinalityWSU) (univ_laog) >= next_gc_univ_laog)
      univ_laog_do_GC();
}

__attribute__((noinline))
static void laog__del_edge ( Lock* src, Lock* dst ) {
   UWord      keyW;
   LAOGLinks* links;
   if (0) VG_(printf)("laog__del_edge enter %p %p\n", src, dst);
   /* Update the out edges for src */
   keyW  = 0;
   links = NULL;
   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)src )) {
      tl_assert(links);
      tl_assert(keyW == (UWord)src);
      links->outs = HG_(delFromWS)( univ_laog, links->outs, (UWord)dst );
   }
   /* Update the in edges for dst */
   keyW  = 0;
   links = NULL;
   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)dst )) {
      tl_assert(links);
      tl_assert(keyW == (UWord)dst);
      links->inns = HG_(delFromWS)( univ_laog, links->inns, (UWord)src );
   }

   /* Remove the exposition of src,dst (if present) */
   {
      LAOGLinkExposition *fm_expo;
      
      LAOGLinkExposition expo;
      expo.src_ga = src->guestaddr;
      expo.dst_ga = dst->guestaddr;
      expo.src_ec = NULL;
      expo.dst_ec = NULL;

      if (VG_(delFromFM) (laog_exposition, 
                          (UWord*)&fm_expo, NULL, (UWord)&expo )) {
         HG_(free) (fm_expo);
      }
   }

   /* deleting edges can increase nr of of WS so check for gc. */
   if (HG_(cardinalityWSU) (univ_laog) >= next_gc_univ_laog)
      univ_laog_do_GC();
   if (0) VG_(printf)("laog__del_edge exit\n");
}

__attribute__((noinline))
static WordSetID /* in univ_laog */ laog__succs ( Lock* lk ) {
   UWord      keyW;
   LAOGLinks* links;
   keyW  = 0;
   links = NULL;
   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)lk )) {
      tl_assert(links);
      tl_assert(keyW == (UWord)lk);
      return links->outs;
   } else {
      return HG_(emptyWS)( univ_laog );
   }
}

__attribute__((noinline))
static WordSetID /* in univ_laog */ laog__preds ( Lock* lk ) {
   UWord      keyW;
   LAOGLinks* links;
   keyW  = 0;
   links = NULL;
   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)lk )) {
      tl_assert(links);
      tl_assert(keyW == (UWord)lk);
      return links->inns;
   } else {
      return HG_(emptyWS)( univ_laog );
   }
}

__attribute__((noinline))
static void laog__sanity_check ( const HChar* who ) {
   UWord i, ws_size;
   UWord* ws_words;
   Lock* me;
   LAOGLinks* links;
   VG_(initIterFM)( laog );
   me = NULL;
   links = NULL;
   if (0) VG_(printf)("laog sanity check\n");
   while (VG_(nextIterFM)( laog, (UWord*)&me,
                                 (UWord*)&links )) {
      tl_assert(me);
      tl_assert(links);
      HG_(getPayloadWS)( &ws_words, &ws_size, univ_laog, links->inns );
      for (i = 0; i < ws_size; i++) {
         if ( ! HG_(elemWS)( univ_laog, 
                             laog__succs( (Lock*)ws_words[i] ), 
                             (UWord)me ))
            goto bad;
      }
      HG_(getPayloadWS)( &ws_words, &ws_size, univ_laog, links->outs );
      for (i = 0; i < ws_size; i++) {
         if ( ! HG_(elemWS)( univ_laog, 
                             laog__preds( (Lock*)ws_words[i] ), 
                             (UWord)me ))
            goto bad;
      }
      me = NULL;
      links = NULL;
   }
   VG_(doneIterFM)( laog );
   return;

  bad:
   VG_(printf)("laog__sanity_check(%s) FAILED\n", who);
   laog__show(who);
   tl_assert(0);
}

/* If there is a path in laog from 'src' to any of the elements in
   'dst', return an arbitrarily chosen element of 'dst' reachable from
   'src'.  If no path exist from 'src' to any element in 'dst', return
   NULL. */
__attribute__((noinline))
static
Lock* laog__do_dfs_from_to ( Lock* src, WordSetID dsts /* univ_lsets */ )
{
   Lock*     ret;
   Word      ssz;
   XArray*   stack;   /* of Lock* */
   WordFM*   visited; /* Lock* -> void, iow, Set(Lock*) */
   Lock*     here;
   WordSetID succs;
   UWord     succs_size, i;
   UWord*    succs_words;
   //laog__sanity_check();

   /* If the destination set is empty, we can never get there from
      'src' :-), so don't bother to try */
   if (HG_(isEmptyWS)( univ_lsets, dsts ))
      return NULL;

   ret     = NULL;
   stack   = VG_(newXA)( HG_(zalloc), "hg.lddft.1", HG_(free), sizeof(Lock*) );
   visited = VG_(newFM)( HG_(zalloc), "hg.lddft.2", HG_(free), NULL/*unboxedcmp*/ );

   (void) VG_(addToXA)( stack, &src );

   while (True) {

      ssz = VG_(sizeXA)( stack );

      if (ssz == 0) { ret = NULL; break; }

      here = *(Lock**) VG_(indexXA)( stack, ssz-1 );
      VG_(dropTailXA)( stack, 1 );

      if (HG_(elemWS)( univ_lsets, dsts, (UWord)here )) { ret = here; break; }

      if (VG_(lookupFM)( visited, NULL, NULL, (UWord)here ))
         continue;

      VG_(addToFM)( visited, (UWord)here, 0 );

      succs = laog__succs( here );
      HG_(getPayloadWS)( &succs_words, &succs_size, univ_laog, succs );
      for (i = 0; i < succs_size; i++)
         (void) VG_(addToXA)( stack, &succs_words[i] );
   }

   VG_(deleteFM)( visited, NULL, NULL );
   VG_(deleteXA)( stack );
   return ret;
}


/* Thread 'thr' is acquiring 'lk'.  Check for inconsistent ordering
   between 'lk' and the locks already held by 'thr' and issue a
   complaint if so.  Also, update the ordering graph appropriately.
*/
__attribute__((noinline))
static void laog__pre_thread_acquires_lock ( 
               Thread* thr, /* NB: BEFORE lock is added */
               Lock*   lk
            )
{
   UWord*   ls_words;
   UWord    ls_size, i;
   Lock*    other;

   /* It may be that 'thr' already holds 'lk' and is recursively
      relocking in.  In this case we just ignore the call. */
   /* NB: univ_lsets really is correct here */
   if (HG_(elemWS)( univ_lsets, thr->locksetA, (UWord)lk ))
      return;

   /* First, the check.  Complain if there is any path in laog from lk
      to any of the locks already held by thr, since if any such path
      existed, it would mean that previously lk was acquired before
      (rather than after, as we are doing here) at least one of those
      locks.
   */
   other = laog__do_dfs_from_to(lk, thr->locksetA);
   if (other) {
      LAOGLinkExposition key, *found;
      /* So we managed to find a path lk --*--> other in the graph,
         which implies that 'lk' should have been acquired before
         'other' but is in fact being acquired afterwards.  We present
         the lk/other arguments to record_error_LockOrder in the order
         in which they should have been acquired. */
      /* Go look in the laog_exposition mapping, to find the allocation
         points for this edge, so we can show the user. */
      key.src_ga = lk->guestaddr;
      key.dst_ga = other->guestaddr;
      key.src_ec = NULL;
      key.dst_ec = NULL;
      found = NULL;
      if (VG_(lookupFM)( laog_exposition,
                         (UWord*)&found, NULL, (UWord)&key )) {
         tl_assert(found != &key);
         tl_assert(found->src_ga == key.src_ga);
         tl_assert(found->dst_ga == key.dst_ga);
         tl_assert(found->src_ec);
         tl_assert(found->dst_ec);
         HG_(record_error_LockOrder)( 
            thr, lk, other,
                 found->src_ec, found->dst_ec, other->acquired_at );
      } else {
         /* Hmm.  This can't happen (can it?) */
         /* Yes, it can happen: see tests/tc14_laog_dinphils.
            Imagine we have 3 philosophers A B C, and the forks
            between them:

                           C

                       fCA   fBC

                      A   fAB   B

            Let's have the following actions:
                   A takes    fCA,fAB
                   A releases fCA,fAB
                   B takes    fAB,fBC
                   B releases fAB,fBC
                   C takes    fBC,fCA
                   C releases fBC,fCA

            Helgrind will report a lock order error when C takes fCA.
            Effectively, we have a deadlock if the following
            sequence is done:
                A takes fCA
                B takes fAB
                C takes fBC

            The error reported is:
              Observed (incorrect) order fBC followed by fCA
            but the stack traces that have established the required order
            are not given.

            This is because there is no pair (fCA, fBC) in laog exposition :
            the laog_exposition records all pairs of locks between a new lock
            taken by a thread and all the already taken locks.
            So, there is no laog_exposition (fCA, fBC) as no thread ever
            first locked fCA followed by fBC.

            In other words, when the deadlock cycle involves more than
            two locks, then helgrind does not report the sequence of
            operations that created the cycle.

            However, we can report the current stack trace (where
            lk is being taken), and the stack trace where other was acquired:
            Effectively, the variable 'other' contains a lock currently
            held by this thread, with its 'acquired_at'. */
                    
         HG_(record_error_LockOrder)(
            thr, lk, other,
                 NULL, NULL, other->acquired_at );
      }
   }

   /* Second, add to laog the pairs
        (old, lk)  |  old <- locks already held by thr
      Since both old and lk are currently held by thr, their acquired_at
      fields must be non-NULL.
   */
   tl_assert(lk->acquired_at);
   HG_(getPayloadWS)( &ls_words, &ls_size, univ_lsets, thr->locksetA );
   for (i = 0; i < ls_size; i++) {
      Lock* old = (Lock*)ls_words[i];
      tl_assert(old->acquired_at);
      laog__add_edge( old, lk );
   }

   /* Why "except_Locks" ?  We're here because a lock is being
      acquired by a thread, and we're in an inconsistent state here.
      See the call points in evhH__post_thread_{r,w}_acquires_lock.
      When called in this inconsistent state, locks__sanity_check duly
      barfs. */
   if (HG_(clo_sanity_flags) & SCE_LAOG)
      all_except_Locks__sanity_check("laog__pre_thread_acquires_lock-post");
}

/* Allocates a duplicate of words. Caller must HG_(free) the result. */
static UWord* UWordV_dup(UWord* words, Word words_size)
{
   UInt i;

   if (words_size == 0)
      return NULL;

   UWord *dup = HG_(zalloc) ("hg.dup.1", (SizeT) words_size * sizeof(UWord));

   for (i = 0; i < words_size; i++)
      dup[i] = words[i];

   return dup;
}

/* Delete from 'laog' any pair mentioning a lock in locksToDelete */

__attribute__((noinline))
static void laog__handle_one_lock_deletion ( Lock* lk )
{
   WordSetID preds, succs;
   UWord preds_size, succs_size, i, j;
   UWord *preds_words, *succs_words;

   preds = laog__preds( lk );
   succs = laog__succs( lk );

   // We need to duplicate the payload, as these can be garbage collected
   // during the del/add operations below.
   HG_(getPayloadWS)( &preds_words, &preds_size, univ_laog, preds );
   preds_words = UWordV_dup(preds_words, preds_size);

   HG_(getPayloadWS)( &succs_words, &succs_size, univ_laog, succs );
   succs_words = UWordV_dup(succs_words, succs_size);

   for (i = 0; i < preds_size; i++)
      laog__del_edge( (Lock*)preds_words[i], lk );

   for (j = 0; j < succs_size; j++)
      laog__del_edge( lk, (Lock*)succs_words[j] );

   for (i = 0; i < preds_size; i++) {
      for (j = 0; j < succs_size; j++) {
         if (preds_words[i] != succs_words[j]) {
            /* This can pass unlocked locks to laog__add_edge, since
               we're deleting stuff.  So their acquired_at fields may
               be NULL. */
            laog__add_edge( (Lock*)preds_words[i], (Lock*)succs_words[j] );
         }
      }
   }

   if (preds_words)
      HG_(free) (preds_words);
   if (succs_words)
      HG_(free) (succs_words);

   // Remove lk information from laog links FM
   {
      LAOGLinks *links;
      Lock* linked_lk;

      if (VG_(delFromFM) (laog, 
                          (UWord*)&linked_lk, (UWord*)&links, (UWord)lk)) {
         tl_assert (linked_lk == lk);
         HG_(free) (links);
      }
   }
   /* FIXME ??? What about removing lock lk data from EXPOSITION ??? */
}

//__attribute__((noinline))
//static void laog__handle_lock_deletions (
//               WordSetID /* in univ_laog */ locksToDelete
//            )
//{
//   Word   i, ws_size;
//   UWord* ws_words;
//
//
//   HG_(getPayloadWS)( &ws_words, &ws_size, univ_lsets, locksToDelete );
//   UWordV_dup call needed here ...
//   for (i = 0; i < ws_size; i++)
//      laog__handle_one_lock_deletion( (Lock*)ws_words[i] );
//
//   if (HG_(clo_sanity_flags) & SCE_LAOG)
//      all__sanity_check("laog__handle_lock_deletions-post");
//}


/*--------------------------------------------------------------*/
/*--- Malloc/free replacements                               ---*/
/*--------------------------------------------------------------*/

typedef
   struct {
      void*       next;    /* required by m_hashtable */
      Addr        payload; /* ptr to actual block    */
      SizeT       szB;     /* size requested         */
      ExeContext* where;   /* where it was allocated */
      Thread*     thr;     /* allocating thread      */
   }
   MallocMeta;

/* A hash table of MallocMetas, used to track malloc'd blocks
   (obviously). */
static VgHashTable *hg_mallocmeta_table = NULL;

/* MallocMeta are small elements. We use a pool to avoid
   the overhead of malloc for each MallocMeta. */
static PoolAlloc *MallocMeta_poolalloc = NULL;

static MallocMeta* new_MallocMeta ( void ) {
   MallocMeta* md = VG_(allocEltPA) (MallocMeta_poolalloc);
   VG_(memset)(md, 0, sizeof(MallocMeta));
   return md;
}
static void delete_MallocMeta ( MallocMeta* md ) {
   VG_(freeEltPA)(MallocMeta_poolalloc, md);
}


/* Allocate a client block and set up the metadata for it. */

static
void* handle_alloc ( ThreadId tid, 
                     SizeT szB, SizeT alignB, Bool is_zeroed )
{
   Addr        p;
   MallocMeta* md;

   tl_assert( ((SSizeT)szB) >= 0 );
   p = (Addr)VG_(cli_malloc)(alignB, szB);
   if (!p) {
      return NULL;
   }
   if (is_zeroed)
      VG_(memset)((void*)p, 0, szB);

   /* Note that map_threads_lookup must succeed (cannot assert), since
      memory can only be allocated by currently alive threads, hence
      they must have an entry in map_threads. */
   md = new_MallocMeta();
   md->payload = p;
   md->szB     = szB;
   md->where   = VG_(record_ExeContext)( tid, 0 );
   md->thr     = map_threads_lookup( tid );

   VG_(HT_add_node)( hg_mallocmeta_table, (VgHashNode*)md );

   /* Tell the lower level memory wranglers. */
   evh__new_mem_heap( p, szB, is_zeroed );

   return (void*)p;
}

/* Re the checks for less-than-zero (also in hg_cli__realloc below):
   Cast to a signed type to catch any unexpectedly negative args.
   We're assuming here that the size asked for is not greater than
   2^31 bytes (for 32-bit platforms) or 2^63 bytes (for 64-bit
   platforms). */
static void* hg_cli__malloc ( ThreadId tid, SizeT n ) {
   if (((SSizeT)n) < 0) return NULL;
   return handle_alloc ( tid, n, VG_(clo_alignment),
                         /*is_zeroed*/False );
}
static void* hg_cli____builtin_new ( ThreadId tid, SizeT n ) {
   if (((SSizeT)n) < 0) return NULL;
   return handle_alloc ( tid, n, VG_(clo_alignment),
                         /*is_zeroed*/False );
}
static void* hg_cli____builtin_vec_new ( ThreadId tid, SizeT n ) {
   if (((SSizeT)n) < 0) return NULL;
   return handle_alloc ( tid, n, VG_(clo_alignment), 
                         /*is_zeroed*/False );
}
static void* hg_cli__memalign ( ThreadId tid, SizeT align, SizeT n ) {
   if (((SSizeT)n) < 0) return NULL;
   return handle_alloc ( tid, n, align, 
                         /*is_zeroed*/False );
}
static void* hg_cli__calloc ( ThreadId tid, SizeT nmemb, SizeT size1 ) {
   if ( ((SSizeT)nmemb) < 0 || ((SSizeT)size1) < 0 ) return NULL;
   return handle_alloc ( tid, nmemb*size1, VG_(clo_alignment),
                         /*is_zeroed*/True );
}


/* Free a client block, including getting rid of the relevant
   metadata. */

static void handle_free ( ThreadId tid, void* p )
{
   MallocMeta *md, *old_md;
   SizeT      szB;

   /* First see if we can find the metadata for 'p'. */
   md = (MallocMeta*) VG_(HT_lookup)( hg_mallocmeta_table, (UWord)p );
   if (!md)
      return; /* apparently freeing a bogus address.  Oh well. */

   tl_assert(md->payload == (Addr)p);
   szB = md->szB;

   /* Nuke the metadata block */
   old_md = (MallocMeta*)
            VG_(HT_remove)( hg_mallocmeta_table, (UWord)p );
   tl_assert(old_md); /* it must be present - we just found it */
   tl_assert(old_md == md);
   tl_assert(old_md->payload == (Addr)p);

   VG_(cli_free)((void*)old_md->payload);
   delete_MallocMeta(old_md);

   /* Tell the lower level memory wranglers. */
   evh__die_mem_heap( (Addr)p, szB );
}

static void hg_cli__free ( ThreadId tid, void* p ) {
   handle_free(tid, p);
}
static void hg_cli____builtin_delete ( ThreadId tid, void* p ) {
   handle_free(tid, p);
}
static void hg_cli____builtin_vec_delete ( ThreadId tid, void* p ) {
   handle_free(tid, p);
}


static void* hg_cli__realloc ( ThreadId tid, void* payloadV, SizeT new_size )
{
   MallocMeta *md, *md_new, *md_tmp;
   SizeT      i;

   Addr payload = (Addr)payloadV;

   if (((SSizeT)new_size) < 0) return NULL;

   md = (MallocMeta*) VG_(HT_lookup)( hg_mallocmeta_table, (UWord)payload );
   if (!md)
      return NULL; /* apparently realloc-ing a bogus address.  Oh well. */
  
   tl_assert(md->payload == payload);

   if (md->szB == new_size) {
      /* size unchanged */
      md->where = VG_(record_ExeContext)(tid, 0);
      return payloadV;
   }

   if (md->szB > new_size) {
      /* new size is smaller */
      md->szB   = new_size;
      md->where = VG_(record_ExeContext)(tid, 0);
      evh__die_mem_heap( md->payload + new_size, md->szB - new_size );
      return payloadV;
   }

   /* else */ {
      /* new size is bigger */
      Addr p_new = (Addr)VG_(cli_malloc)(VG_(clo_alignment), new_size);

      /* First half kept and copied, second half new */
      // FIXME: shouldn't we use a copier which implements the
      // memory state machine?
      evh__copy_mem( payload, p_new, md->szB );
      evh__new_mem_heap ( p_new + md->szB, new_size - md->szB,
                          /*inited*/False );
      /* FIXME: can anything funny happen here?  specifically, if the
         old range contained a lock, then die_mem_heap will complain.
         Is that the correct behaviour?  Not sure. */
      evh__die_mem_heap( payload, md->szB );

      /* Copy from old to new */
      for (i = 0; i < md->szB; i++)
         ((UChar*)p_new)[i] = ((UChar*)payload)[i];

      /* Because the metadata hash table is index by payload address,
         we have to get rid of the old hash table entry and make a new
         one.  We can't just modify the existing metadata in place,
         because then it would (almost certainly) be in the wrong hash
         chain. */
      md_new = new_MallocMeta();
      *md_new = *md;

      md_tmp = VG_(HT_remove)( hg_mallocmeta_table, payload );
      tl_assert(md_tmp);
      tl_assert(md_tmp == md);

      VG_(cli_free)((void*)md->payload);
      delete_MallocMeta(md);

      /* Update fields */
      md_new->where   = VG_(record_ExeContext)( tid, 0 );
      md_new->szB     = new_size;
      md_new->payload = p_new;
      md_new->thr     = map_threads_lookup( tid );

      /* and add */
      VG_(HT_add_node)( hg_mallocmeta_table, (VgHashNode*)md_new );

      return (void*)p_new;
   }  
}

static SizeT hg_cli_malloc_usable_size ( ThreadId tid, void* p )
{
   MallocMeta *md = VG_(HT_lookup)( hg_mallocmeta_table, (UWord)p );

   // There may be slop, but pretend there isn't because only the asked-for
   // area will have been shadowed properly.
   return ( md ? md->szB : 0 );
}


/* For error creation: map 'data_addr' to a malloc'd chunk, if any.
   Slow linear search.  With a bit of hash table help if 'data_addr'
   is either the start of a block or up to 15 word-sized steps along
   from the start of a block. */

static inline Bool addr_is_in_MM_Chunk( MallocMeta* mm, Addr a )
{
   /* Accept 'a' as within 'mm' if 'mm's size is zero and 'a' points
      right at it. */
  if (UNLIKELY(mm->szB == 0 && a == mm->payload))
     return True;
  /* else normal interval rules apply */
  if (LIKELY(a < mm->payload)) return False;
  if (LIKELY(a >= mm->payload + mm->szB)) return False;
  return True;
}

Bool HG_(mm_find_containing_block)( /*OUT*/ExeContext** where,
                                    /*OUT*/UInt*        tnr,
                                    /*OUT*/Addr*        payload,
                                    /*OUT*/SizeT*       szB,
                                    Addr                data_addr )
{
   MallocMeta* mm;
   Int i;
   const Int n_fast_check_words = 16;

   /* First, do a few fast searches on the basis that data_addr might
      be exactly the start of a block or up to 15 words inside.  This
      can happen commonly via the creq
      _VG_USERREQ__HG_CLEAN_MEMORY_HEAPBLOCK. */
   for (i = 0; i < n_fast_check_words; i++) {
      mm = VG_(HT_lookup)( hg_mallocmeta_table,
                           data_addr - (UWord)(UInt)i * sizeof(UWord) );
      if (UNLIKELY(mm && addr_is_in_MM_Chunk(mm, data_addr)))
         goto found;
   }

   /* Well, this totally sucks.  But without using an interval tree or
      some such, it's hard to see how to do better.  We have to check
      every block in the entire table. */
   VG_(HT_ResetIter)(hg_mallocmeta_table);
   while ( (mm = VG_(HT_Next)(hg_mallocmeta_table)) ) {
      if (UNLIKELY(addr_is_in_MM_Chunk(mm, data_addr)))
         goto found;
   }

   /* Not found.  Bah. */
   return False;
   /*NOTREACHED*/

  found:
   tl_assert(mm);
   tl_assert(addr_is_in_MM_Chunk(mm, data_addr));
   if (where)   *where   = mm->where;
   if (tnr)     *tnr     = mm->thr->errmsg_index;
   if (payload) *payload = mm->payload;
   if (szB)     *szB     = mm->szB;
   return True;
}


/*--------------------------------------------------------------*/
/*--- Instrumentation                                        ---*/
/*--------------------------------------------------------------*/

#define unop(_op, _arg1)         IRExpr_Unop((_op),(_arg1))
#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2))
#define mkexpr(_tmp)             IRExpr_RdTmp((_tmp))
#define mkU32(_n)                IRExpr_Const(IRConst_U32(_n))
#define mkU64(_n)                IRExpr_Const(IRConst_U64(_n))
#define assign(_t, _e)           IRStmt_WrTmp((_t), (_e))

/* This takes and returns atoms, of course.  Not full IRExprs. */
static IRExpr* mk_And1 ( IRSB* sbOut, IRExpr* arg1, IRExpr* arg2 )
{
   tl_assert(arg1 && arg2);
   tl_assert(isIRAtom(arg1));
   tl_assert(isIRAtom(arg2));
   /* Generate 32to1(And32(1Uto32(arg1), 1Uto32(arg2))).  Appalling
      code, I know. */
   IRTemp wide1 = newIRTemp(sbOut->tyenv, Ity_I32);
   IRTemp wide2 = newIRTemp(sbOut->tyenv, Ity_I32);
   IRTemp anded = newIRTemp(sbOut->tyenv, Ity_I32);
   IRTemp res   = newIRTemp(sbOut->tyenv, Ity_I1);
   addStmtToIRSB(sbOut, assign(wide1, unop(Iop_1Uto32, arg1)));
   addStmtToIRSB(sbOut, assign(wide2, unop(Iop_1Uto32, arg2)));
   addStmtToIRSB(sbOut, assign(anded, binop(Iop_And32, mkexpr(wide1),
                                                       mkexpr(wide2))));
   addStmtToIRSB(sbOut, assign(res, unop(Iop_32to1, mkexpr(anded))));
   return mkexpr(res);
}

static void instrument_mem_access ( IRSB*   sbOut, 
                                    IRExpr* addr,
                                    Int     szB,
                                    Bool    isStore,
                                    Int     hWordTy_szB,
                                    Int     goff_sp,
                                    IRExpr* guard ) /* NULL => True */
{
   IRType   tyAddr   = Ity_INVALID;
   const HChar* hName    = NULL;
   void*    hAddr    = NULL;
   Int      regparms = 0;
   IRExpr** argv     = NULL;
   IRDirty* di       = NULL;

   // THRESH is the size of the window above SP (well,
   // mostly above) that we assume implies a stack reference.
   const Int THRESH = 4096 * 4; // somewhat arbitrary
   const Int rz_szB = VG_STACK_REDZONE_SZB;

   tl_assert(isIRAtom(addr));
   tl_assert(hWordTy_szB == 4 || hWordTy_szB == 8);

   tyAddr = typeOfIRExpr( sbOut->tyenv, addr );
   tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);

   /* So the effective address is in 'addr' now. */
   regparms = 1; // unless stated otherwise
   if (isStore) {
      switch (szB) {
         case 1:
            hName = "evh__mem_help_cwrite_1";
            hAddr = &evh__mem_help_cwrite_1;
            argv = mkIRExprVec_1( addr );
            break;
         case 2:
            hName = "evh__mem_help_cwrite_2";
            hAddr = &evh__mem_help_cwrite_2;
            argv = mkIRExprVec_1( addr );
            break;
         case 4:
            hName = "evh__mem_help_cwrite_4";
            hAddr = &evh__mem_help_cwrite_4;
            argv = mkIRExprVec_1( addr );
            break;
         case 8:
            hName = "evh__mem_help_cwrite_8";
            hAddr = &evh__mem_help_cwrite_8;
            argv = mkIRExprVec_1( addr );
            break;
         default:
            tl_assert(szB > 8 && szB <= 512); /* stay sane */
            regparms = 2;
            hName = "evh__mem_help_cwrite_N";
            hAddr = &evh__mem_help_cwrite_N;
            argv = mkIRExprVec_2( addr, mkIRExpr_HWord( szB ));
            break;
      }
   } else {
      switch (szB) {
         case 1:
            hName = "evh__mem_help_cread_1";
            hAddr = &evh__mem_help_cread_1;
            argv = mkIRExprVec_1( addr );
            break;
         case 2:
            hName = "evh__mem_help_cread_2";
            hAddr = &evh__mem_help_cread_2;
            argv = mkIRExprVec_1( addr );
            break;
         case 4:
            hName = "evh__mem_help_cread_4";
            hAddr = &evh__mem_help_cread_4;
            argv = mkIRExprVec_1( addr );
            break;
         case 8:
            hName = "evh__mem_help_cread_8";
            hAddr = &evh__mem_help_cread_8;
            argv = mkIRExprVec_1( addr );
            break;
         default: 
            tl_assert(szB > 8 && szB <= 512); /* stay sane */
            regparms = 2;
            hName = "evh__mem_help_cread_N";
            hAddr = &evh__mem_help_cread_N;
            argv = mkIRExprVec_2( addr, mkIRExpr_HWord( szB ));
            break;
      }
   }

   /* Create the helper. */
   tl_assert(hName);
   tl_assert(hAddr);
   tl_assert(argv);
   di = unsafeIRDirty_0_N( regparms,
                           hName, VG_(fnptr_to_fnentry)( hAddr ),
                           argv );

   if (! HG_(clo_check_stack_refs)) {
      /* We're ignoring memory references which are (obviously) to the
         stack.  In fact just skip stack refs that are within 4 pages
         of SP (SP - the redzone, really), as that's simple, easy, and
         filters out most stack references. */
      /* Generate the guard condition: "(addr - (SP - RZ)) >u N", for
         some arbitrary N.  If that is true then addr is outside the
         range (SP - RZ .. SP + N - RZ).  If N is smallish (a few
         pages) then we can say addr is within a few pages of SP and
         so can't possibly be a heap access, and so can be skipped.

         Note that the condition simplifies to
            (addr - SP + RZ) >u N
         which generates better code in x86/amd64 backends, but it does
         not unfortunately simplify to
            (addr - SP) >u (N - RZ)
         (would be beneficial because N - RZ is a constant) because
         wraparound arithmetic messes up the comparison.  eg.
         20 >u 10 == True,
         but (20 - 15) >u (10 - 15) == 5 >u (MAXINT-5) == False.
      */
      IRTemp sp = newIRTemp(sbOut->tyenv, tyAddr);
      addStmtToIRSB( sbOut, assign(sp, IRExpr_Get(goff_sp, tyAddr)));

      /* "addr - SP" */
      IRTemp addr_minus_sp = newIRTemp(sbOut->tyenv, tyAddr);
      addStmtToIRSB(
         sbOut,
         assign(addr_minus_sp,
                tyAddr == Ity_I32
                   ? binop(Iop_Sub32, addr, mkexpr(sp))
                   : binop(Iop_Sub64, addr, mkexpr(sp)))
      );

      /* "addr - SP + RZ" */
      IRTemp diff = newIRTemp(sbOut->tyenv, tyAddr);
      addStmtToIRSB(
         sbOut,
         assign(diff,
                tyAddr == Ity_I32 
                   ? binop(Iop_Add32, mkexpr(addr_minus_sp), mkU32(rz_szB))
                   : binop(Iop_Add64, mkexpr(addr_minus_sp), mkU64(rz_szB)))
      );

      /* guardA == "guard on the address" */
      IRTemp guardA = newIRTemp(sbOut->tyenv, Ity_I1);
      addStmtToIRSB(
         sbOut,
         assign(guardA,
                tyAddr == Ity_I32 
                   ? binop(Iop_CmpLT32U, mkU32(THRESH), mkexpr(diff))
                   : binop(Iop_CmpLT64U, mkU64(THRESH), mkexpr(diff)))
      );
      di->guard = mkexpr(guardA);
   }

   /* If there's a guard on the access itself (as supplied by the
      caller of this routine), we need to AND that in to any guard we
      might already have. */
   if (guard) {
      di->guard = mk_And1(sbOut, di->guard, guard);
   }

   /* Add the helper. */
   addStmtToIRSB( sbOut, IRStmt_Dirty(di) );
}


/* Figure out if GA is a guest code address in the dynamic linker, and
   if so return True.  Otherwise (and in case of any doubt) return
   False.  (sidedly safe w/ False as the safe value) */
static Bool is_in_dynamic_linker_shared_object( Addr ga )
{
   DebugInfo* dinfo;
   const HChar* soname;
   if (0) return False;

   dinfo = VG_(find_DebugInfo)( ga );
   if (!dinfo) return False;

   soname = VG_(DebugInfo_get_soname)(dinfo);
   tl_assert(soname);
   if (0) VG_(printf)("%s\n", soname);

#  if defined(VGO_linux)
   if (VG_STREQ(soname, VG_U_LD_LINUX_SO_3))        return True;
   if (VG_STREQ(soname, VG_U_LD_LINUX_SO_2))        return True;
   if (VG_STREQ(soname, VG_U_LD_LINUX_X86_64_SO_2)) return True;
   if (VG_STREQ(soname, VG_U_LD64_SO_1))            return True;
   if (VG_STREQ(soname, VG_U_LD64_SO_2))            return True;
   if (VG_STREQ(soname, VG_U_LD_SO_1))              return True;
   if (VG_STREQ(soname, VG_U_LD_LINUX_AARCH64_SO_1)) return True;
   if (VG_STREQ(soname, VG_U_LD_LINUX_ARMHF_SO_3))  return True;
#  elif defined(VGO_darwin)
   if (VG_STREQ(soname, VG_U_DYLD)) return True;
#  elif defined(VGO_solaris)
   if (VG_STREQ(soname, VG_U_LD_SO_1)) return True;
#  else
#    error "Unsupported OS"
#  endif
   return False;
}

static
IRSB* hg_instrument ( VgCallbackClosure* closure,
                      IRSB* bbIn,
                      const VexGuestLayout* layout,
                      const VexGuestExtents* vge,
                      const VexArchInfo* archinfo_host,
                      IRType gWordTy, IRType hWordTy )
{
   Int     i;
   IRSB*   bbOut;
   Addr    cia; /* address of current insn */
   IRStmt* st;
   Bool    inLDSO = False;
   Addr    inLDSOmask4K = 1; /* mismatches on first check */

   const Int goff_sp = layout->offset_SP;

   if (gWordTy != hWordTy) {
      /* We don't currently support this case. */
      VG_(tool_panic)("host/guest word size mismatch");
   }

   if (VKI_PAGE_SIZE < 4096 || VG_(log2)(VKI_PAGE_SIZE) == -1) {
      VG_(tool_panic)("implausible or too-small VKI_PAGE_SIZE");
   }

   /* Set up BB */
   bbOut           = emptyIRSB();
   bbOut->tyenv    = deepCopyIRTypeEnv(bbIn->tyenv);
   bbOut->next     = deepCopyIRExpr(bbIn->next);
   bbOut->jumpkind = bbIn->jumpkind;
   bbOut->offsIP   = bbIn->offsIP;

   // Copy verbatim any IR preamble preceding the first IMark
   i = 0;
   while (i < bbIn->stmts_used && bbIn->stmts[i]->tag != Ist_IMark) {
      addStmtToIRSB( bbOut, bbIn->stmts[i] );
      i++;
   }

   // Get the first statement, and initial cia from it
   tl_assert(bbIn->stmts_used > 0);
   tl_assert(i < bbIn->stmts_used);
   st = bbIn->stmts[i];
   tl_assert(Ist_IMark == st->tag);
   cia = st->Ist.IMark.addr;
   st = NULL;

   for (/*use current i*/; i < bbIn->stmts_used; i++) {
      st = bbIn->stmts[i];
      tl_assert(st);
      tl_assert(isFlatIRStmt(st));
      switch (st->tag) {
         case Ist_NoOp:
         case Ist_AbiHint:
         case Ist_Put:
         case Ist_PutI:
         case Ist_Exit:
            /* None of these can contain any memory references. */
            break;

         case Ist_IMark:
            /* no mem refs, but note the insn address. */
            cia = st->Ist.IMark.addr;
            /* Don't instrument the dynamic linker.  It generates a
               lot of races which we just expensively suppress, so
               it's pointless.

               Avoid flooding is_in_dynamic_linker_shared_object with
               requests by only checking at transitions between 4K
               pages. */
            if ((cia & ~(Addr)0xFFF) != inLDSOmask4K) {
               if (0) VG_(printf)("NEW %#lx\n", cia);
               inLDSOmask4K = cia & ~(Addr)0xFFF;
               inLDSO = is_in_dynamic_linker_shared_object(cia);
            } else {
               if (0) VG_(printf)("old %#lx\n", cia);
            }
            break;

         case Ist_MBE:
            switch (st->Ist.MBE.event) {
               case Imbe_Fence:
               case Imbe_CancelReservation:
                  break; /* not interesting */
               default:
                  goto unhandled;
            }
            break;

         case Ist_CAS: {
            /* Atomic read-modify-write cycle.  Just pretend it's a
               read. */
            IRCAS* cas    = st->Ist.CAS.details;
            Bool   isDCAS = cas->oldHi != IRTemp_INVALID;
            if (isDCAS) {
               tl_assert(cas->expdHi);
               tl_assert(cas->dataHi);
            } else {
               tl_assert(!cas->expdHi);
               tl_assert(!cas->dataHi);
            }
            /* Just be boring about it. */
            if (!inLDSO) {
               instrument_mem_access(
                  bbOut,
                  cas->addr,
                  (isDCAS ? 2 : 1)
                     * sizeofIRType(typeOfIRExpr(bbIn->tyenv, cas->dataLo)),
                  False/*!isStore*/,
                  sizeofIRType(hWordTy), goff_sp,
                  NULL/*no-guard*/
               );
            }
            break;
         }

         case Ist_LLSC: {
            /* We pretend store-conditionals don't exist, viz, ignore
               them.  Whereas load-linked's are treated the same as
               normal loads. */
            IRType dataTy;
            if (st->Ist.LLSC.storedata == NULL) {
               /* LL */
               dataTy = typeOfIRTemp(bbIn->tyenv, st->Ist.LLSC.result);
               if (!inLDSO) {
                  instrument_mem_access(
                     bbOut,
                     st->Ist.LLSC.addr,
                     sizeofIRType(dataTy),
                     False/*!isStore*/,
                     sizeofIRType(hWordTy), goff_sp,
                     NULL/*no-guard*/
                  );
               }
            } else {
               /* SC */
               /*ignore */
            }
            break;
         }

         case Ist_Store:
            if (!inLDSO) {
               instrument_mem_access( 
                  bbOut, 
                  st->Ist.Store.addr, 
                  sizeofIRType(typeOfIRExpr(bbIn->tyenv, st->Ist.Store.data)),
                  True/*isStore*/,
                  sizeofIRType(hWordTy), goff_sp,
                  NULL/*no-guard*/
               );
            }
            break;

         case Ist_StoreG: {
            IRStoreG* sg   = st->Ist.StoreG.details;
            IRExpr*   data = sg->data;
            IRExpr*   addr = sg->addr;
            IRType    type = typeOfIRExpr(bbIn->tyenv, data);
            tl_assert(type != Ity_INVALID);
            instrument_mem_access( bbOut, addr, sizeofIRType(type),
                                   True/*isStore*/,
                                   sizeofIRType(hWordTy),
                                   goff_sp, sg->guard );
            break;
         }

         case Ist_LoadG: {
            IRLoadG* lg       = st->Ist.LoadG.details;
            IRType   type     = Ity_INVALID; /* loaded type */
            IRType   typeWide = Ity_INVALID; /* after implicit widening */
            IRExpr*  addr     = lg->addr;
            typeOfIRLoadGOp(lg->cvt, &typeWide, &type);
            tl_assert(type != Ity_INVALID);
            instrument_mem_access( bbOut, addr, sizeofIRType(type),
                                   False/*!isStore*/,
                                   sizeofIRType(hWordTy),
                                   goff_sp, lg->guard );
            break;
         }

         case Ist_WrTmp: {
            IRExpr* data = st->Ist.WrTmp.data;
            if (data->tag == Iex_Load) {
               if (!inLDSO) {
                  instrument_mem_access(
                     bbOut,
                     data->Iex.Load.addr,
                     sizeofIRType(data->Iex.Load.ty),
                     False/*!isStore*/,
                     sizeofIRType(hWordTy), goff_sp,
                     NULL/*no-guard*/
                  );
               }
            }
            break;
         }

         case Ist_Dirty: {
            Int      dataSize;
            IRDirty* d = st->Ist.Dirty.details;
            if (d->mFx != Ifx_None) {
               /* This dirty helper accesses memory.  Collect the
                  details. */
               tl_assert(d->mAddr != NULL);
               tl_assert(d->mSize != 0);
               dataSize = d->mSize;
               if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify) {
                  if (!inLDSO) {
                     instrument_mem_access( 
                        bbOut, d->mAddr, dataSize, False/*!isStore*/,
                        sizeofIRType(hWordTy), goff_sp, NULL/*no-guard*/
                     );
                  }
               }
               if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify) {
                  if (!inLDSO) {
                     instrument_mem_access( 
                        bbOut, d->mAddr, dataSize, True/*isStore*/,
                        sizeofIRType(hWordTy), goff_sp, NULL/*no-guard*/
                     );
                  }
               }
            } else {
               tl_assert(d->mAddr == NULL);
               tl_assert(d->mSize == 0);
            }
            break;
         }

         default:
         unhandled:
            ppIRStmt(st);
            tl_assert(0);

      } /* switch (st->tag) */

      addStmtToIRSB( bbOut, st );
   } /* iterate over bbIn->stmts */

   return bbOut;
}

#undef binop
#undef mkexpr
#undef mkU32
#undef mkU64
#undef assign


/*----------------------------------------------------------------*/
/*--- Client requests                                          ---*/
/*----------------------------------------------------------------*/

/* Sheesh.  Yet another goddam finite map. */
static WordFM* map_pthread_t_to_Thread = NULL; /* pthread_t -> Thread* */

static void map_pthread_t_to_Thread_INIT ( void ) {
   if (UNLIKELY(map_pthread_t_to_Thread == NULL)) {
      map_pthread_t_to_Thread = VG_(newFM)( HG_(zalloc), "hg.mpttT.1", 
                                            HG_(free), NULL );
   }
}

/* A list of Ada dependent tasks and their masters. Used for implementing
   the Ada task termination semantic as implemented by the
   gcc gnat Ada runtime. */
typedef
   struct { 
      void* dependent; // Ada Task Control Block of the Dependent
      void* master;    // ATCB of the master
      Word  master_level; // level of dependency between master and dependent
      Thread* hg_dependent; // helgrind Thread* for dependent task.
   }
   GNAT_dmml;
static XArray* gnat_dmmls;   /* of GNAT_dmml */
static void gnat_dmmls_INIT (void)
{
   if (UNLIKELY(gnat_dmmls == NULL)) {
      gnat_dmmls = VG_(newXA) (HG_(zalloc), "hg.gnat_md.1",
                               HG_(free),
                               sizeof(GNAT_dmml) );
   }
}
static void print_monitor_help ( void )
{
   VG_(gdb_printf) 
      (
"\n"
"helgrind monitor commands:\n"
"  info locks [lock_addr]  : show status of lock at addr lock_addr\n"
"           with no lock_addr, show status of all locks\n"
"  accesshistory <addr> [<len>]   : show access history recorded\n"
"                     for <len> (or 1) bytes at <addr>\n"
"\n");
}

/* return True if request recognised, False otherwise */
static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
{
   HChar* wcmd;
   HChar s[VG_(strlen(req))]; /* copy for strtok_r */
   HChar *ssaveptr;
   Int   kwdid;

   VG_(strcpy) (s, req);

   wcmd = VG_(strtok_r) (s, " ", &ssaveptr);
   /* NB: if possible, avoid introducing a new command below which
      starts with the same first letter(s) as an already existing
      command. This ensures a shorter abbreviation for the user. */
   switch (VG_(keyword_id) 
           ("help info accesshistory", 
            wcmd, kwd_report_duplicated_matches)) {
   case -2: /* multiple matches */
      return True;
   case -1: /* not found */
      return False;
   case  0: /* help */
      print_monitor_help();
      return True;
   case  1: /* info */
      wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
      switch (kwdid = VG_(keyword_id) 
              ("locks",
               wcmd, kwd_report_all)) {
      case -2:
      case -1: 
         break;
      case 0: // locks
         {
            const HChar* wa;
            Addr lk_addr = 0;
            Bool lk_shown = False;
            Bool all_locks = True;
            Int i;
            Lock* lk;

            wa = VG_(strtok_r) (NULL, " ", &ssaveptr);
            if (wa != NULL) {
               if (VG_(parse_Addr) (&wa, &lk_addr) )
                  all_locks = False;
               else {
                  VG_(gdb_printf) ("missing or malformed address\n");
               }
            }
            for (i = 0, lk = admin_locks;  lk;  i++, lk = lk->admin_next) {
               if (all_locks || lk_addr == lk->guestaddr) {
                  pp_Lock(0, lk,
                          True /* show_lock_addrdescr */,
                          False /* show_internal_data */);
                  lk_shown = True;
               }
            }
            if (i == 0)
               VG_(gdb_printf) ("no locks\n");
            if (!all_locks && !lk_shown)
               VG_(gdb_printf) ("lock with address %p not found\n",
                                (void*)lk_addr);
         }
         break;
      default:
         tl_assert(0);
      }
      return True;

   case  2: /* accesshistory */
      {
         Addr address;
         SizeT szB = 1;
         if (VG_(strtok_get_address_and_size) (&address, &szB, &ssaveptr)) {
            if (szB >= 1) 
               libhb_event_map_access_history (address, szB, HG_(print_access));
            else
               VG_(gdb_printf) ("len must be >=1\n");
         }
         return True;
      }

   default: 
      tl_assert(0);
      return False;
   }
}

static 
Bool hg_handle_client_request ( ThreadId tid, UWord* args, UWord* ret)
{
   if (!VG_IS_TOOL_USERREQ('H','G',args[0])
       && VG_USERREQ__GDB_MONITOR_COMMAND   != args[0])
      return False;

   /* Anything that gets past the above check is one of ours, so we
      should be able to handle it. */

   /* default, meaningless return value, unless otherwise set */
   *ret = 0;

   switch (args[0]) {

      /* --- --- User-visible client requests --- --- */

      case VG_USERREQ__HG_CLEAN_MEMORY:
         if (0) VG_(printf)("VG_USERREQ__HG_CLEAN_MEMORY(%#lx,%lu)\n",
                            args[1], args[2]);
         /* Call die_mem to (expensively) tidy up properly, if there
            are any held locks etc in the area.  Calling evh__die_mem
            and then evh__new_mem is a bit inefficient; probably just
            the latter would do. */
         if (args[2] > 0) { /* length */
            evh__die_mem(args[1], args[2]);
            /* and then set it to New */
            evh__new_mem(args[1], args[2]);
         }
         break;

      case _VG_USERREQ__HG_CLEAN_MEMORY_HEAPBLOCK: {
         Addr  payload = 0;
         SizeT pszB = 0;
         if (0) VG_(printf)("VG_USERREQ__HG_CLEAN_MEMORY_HEAPBLOCK(%#lx)\n",
                            args[1]);
         if (HG_(mm_find_containing_block)(NULL, NULL, 
                                           &payload, &pszB, args[1])) {
            if (pszB > 0) {
               evh__die_mem(payload, pszB);
               evh__new_mem(payload, pszB);
            }
            *ret = pszB;
         } else {
            *ret = (UWord)-1;
         }
         break;
      }

      case _VG_USERREQ__HG_ARANGE_MAKE_UNTRACKED:
         if (0) VG_(printf)("HG_ARANGE_MAKE_UNTRACKED(%#lx,%lu)\n",
                            args[1], args[2]);
         if (args[2] > 0) { /* length */
            evh__untrack_mem(args[1], args[2]);
         }
         break;

      case _VG_USERREQ__HG_ARANGE_MAKE_TRACKED:
         if (0) VG_(printf)("HG_ARANGE_MAKE_TRACKED(%#lx,%lu)\n",
                            args[1], args[2]);
         if (args[2] > 0) { /* length */
            evh__new_mem(args[1], args[2]);
         }
         break;

      case _VG_USERREQ__HG_GET_ABITS:
         if (0) VG_(printf)("HG_GET_ABITS(%#lx,%#lx,%lu)\n",
                            args[1], args[2], args[3]);
         UChar *zzabit = (UChar *) args[2];
         if (zzabit == NULL 
             || VG_(am_is_valid_for_client)((Addr)zzabit, (SizeT)args[3],
                                            VKI_PROT_READ|VKI_PROT_WRITE))
            *ret = (UWord) libhb_srange_get_abits ((Addr)   args[1],
                                                   (UChar*) args[2],
                                                   (SizeT)  args[3]);
         else
            *ret = -1;
         break;

      /* --- --- Client requests for Helgrind's use only --- --- */

      /* Some thread is telling us its pthread_t value.  Record the
         binding between that and the associated Thread*, so we can
         later find the Thread* again when notified of a join by the
         thread. */
      case _VG_USERREQ__HG_SET_MY_PTHREAD_T: {
         Thread* my_thr = NULL;
         if (0)
         VG_(printf)("SET_MY_PTHREAD_T (tid %d): pthread_t = %p\n", (Int)tid,
                     (void*)args[1]);
         map_pthread_t_to_Thread_INIT();
         my_thr = map_threads_maybe_lookup( tid );
         /* This assertion should hold because the map_threads (tid to
            Thread*) binding should have been made at the point of
            low-level creation of this thread, which should have
            happened prior to us getting this client request for it.
            That's because this client request is sent from
            client-world from the 'thread_wrapper' function, which
            only runs once the thread has been low-level created. */
         tl_assert(my_thr != NULL);
         /* So now we know that (pthread_t)args[1] is associated with
            (Thread*)my_thr.  Note that down. */
         if (0)
         VG_(printf)("XXXX: bind pthread_t %p to Thread* %p\n",
                     (void*)args[1], (void*)my_thr );
         VG_(addToFM)( map_pthread_t_to_Thread, (UWord)args[1], (UWord)my_thr );

         if (my_thr->coretid != 1) {
            /* FIXME: hardwires assumption about identity of the root thread. */
            if (HG_(clo_ignore_thread_creation)) {
               HG_(thread_leave_pthread_create)(my_thr);
               HG_(thread_leave_synchr)(my_thr);
               tl_assert(my_thr->synchr_nesting == 0);
            }
         }
         break;
      }

      case _VG_USERREQ__HG_PTH_API_ERROR: {
         Thread* my_thr = NULL;
         map_pthread_t_to_Thread_INIT();
         my_thr = map_threads_maybe_lookup( tid );
         tl_assert(my_thr); /* See justification above in SET_MY_PTHREAD_T */
         HG_(record_error_PthAPIerror)(
            my_thr, (HChar*)args[1], (UWord)args[2], (HChar*)args[3] );
         break;
      }

      /* This thread (tid) has completed a join with the quitting
         thread whose pthread_t is in args[1]. */
      case _VG_USERREQ__HG_PTHREAD_JOIN_POST: {
         Thread* thr_q = NULL; /* quitter Thread* */
         Bool    found = False;
         if (0)
         VG_(printf)("NOTIFY_JOIN_COMPLETE (tid %d): quitter = %p\n", (Int)tid,
                     (void*)args[1]);
         map_pthread_t_to_Thread_INIT();
         found = VG_(lookupFM)( map_pthread_t_to_Thread, 
                                NULL, (UWord*)&thr_q, (UWord)args[1] );
          /* Can this fail?  It would mean that our pthread_join
             wrapper observed a successful join on args[1] yet that
             thread never existed (or at least, it never lodged an
             entry in the mapping (via SET_MY_PTHREAD_T)).  Which
             sounds like a bug in the threads library. */
         // FIXME: get rid of this assertion; handle properly
         tl_assert(found);
         if (found) {
            if (0)
            VG_(printf)(".................... quitter Thread* = %p\n", 
                        thr_q);
            evh__HG_PTHREAD_JOIN_POST( tid, thr_q );
         }
         break;
      }

      /* This thread (tid) is informing us of its master. */
      case _VG_USERREQ__HG_GNAT_MASTER_HOOK: {
         GNAT_dmml dmml;
         dmml.dependent = (void*)args[1];
         dmml.master = (void*)args[2];
         dmml.master_level = (Word)args[3];
         dmml.hg_dependent = map_threads_maybe_lookup( tid );
         tl_assert(dmml.hg_dependent);

         if (0)
         VG_(printf)("HG_GNAT_MASTER_HOOK (tid %d): "
                     "dependent = %p master = %p master_level = %ld"
                     " dependent Thread* = %p\n",
                     (Int)tid, dmml.dependent, dmml.master, dmml.master_level,
                     dmml.hg_dependent);
         gnat_dmmls_INIT();
         VG_(addToXA) (gnat_dmmls, &dmml);
         break;
      }

      /* This thread (tid) is informing us that it has completed a
         master. */
      case _VG_USERREQ__HG_GNAT_MASTER_COMPLETED_HOOK: {
         Word n;
         const Thread *stayer = map_threads_maybe_lookup( tid );
         const void *master = (void*)args[1];
         const Word master_level = (Word) args[2];
         tl_assert(stayer);

         if (0)
         VG_(printf)("HG_GNAT_MASTER_COMPLETED_HOOK (tid %d): "
                     "self_id = %p master_level = %ld Thread* = %p\n",
                     (Int)tid, master, master_level, stayer);

         gnat_dmmls_INIT();
         /* Reverse loop on the array, simulating a pthread_join for
            the Dependent tasks of the completed master, and removing
            them from the array. */
         for (n = VG_(sizeXA) (gnat_dmmls) - 1; n >= 0; n--) {
            GNAT_dmml *dmml = (GNAT_dmml*) VG_(indexXA)(gnat_dmmls, n);
            if (dmml->master == master
                && dmml->master_level == master_level) {
               if (0)
               VG_(printf)("quitter %p dependency to stayer %p\n",
                           dmml->hg_dependent->hbthr,  stayer->hbthr);
               tl_assert(dmml->hg_dependent->hbthr != stayer->hbthr);
               generate_quitter_stayer_dependence (dmml->hg_dependent->hbthr,
                                                   stayer->hbthr);
               VG_(removeIndexXA) (gnat_dmmls, n);
            }
         }
         break;
      }

      /* EXPOSITION only: by intercepting lock init events we can show
         the user where the lock was initialised, rather than only
         being able to show where it was first locked.  Intercepting
         lock initialisations is not necessary for the basic operation
         of the race checker. */
      case _VG_USERREQ__HG_PTHREAD_MUTEX_INIT_POST:
         evh__HG_PTHREAD_MUTEX_INIT_POST( tid, (void*)args[1], args[2] );
         break;

      /* mutex=arg[1], mutex_is_init=arg[2] */
      case _VG_USERREQ__HG_PTHREAD_MUTEX_DESTROY_PRE:
         evh__HG_PTHREAD_MUTEX_DESTROY_PRE( tid, (void*)args[1], args[2] != 0 );
         break;

      case _VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_PRE:   // pth_mx_t*
         HG_(thread_enter_synchr)(map_threads_maybe_lookup(tid));
         if (HG_(get_pthread_create_nesting_level)(tid) == 0)
            evh__HG_PTHREAD_MUTEX_UNLOCK_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_POST:  // pth_mx_t*
         if (HG_(get_pthread_create_nesting_level)(tid) == 0)
            evh__HG_PTHREAD_MUTEX_UNLOCK_POST( tid, (void*)args[1] );
         HG_(thread_leave_synchr)(map_threads_maybe_lookup(tid));
         break;

      case _VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_PRE:     // pth_mx_t*
         HG_(thread_enter_synchr)(map_threads_maybe_lookup(tid));
         if (HG_(get_pthread_create_nesting_level)(tid) == 0)
            evh__HG_PTHREAD_MUTEX_LOCK_PRE( tid, (void*)args[1], args[2] );
         break;

      case _VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_POST:    // pth_mx_t*, long
         if ((args[2] == True) // lock actually taken
             && (HG_(get_pthread_create_nesting_level)(tid) == 0))
            evh__HG_PTHREAD_MUTEX_LOCK_POST( tid, (void*)args[1] );
         HG_(thread_leave_synchr)(map_threads_maybe_lookup(tid));
         break;

      /* This thread is about to do pthread_cond_signal on the
         pthread_cond_t* in arg[1].  Ditto pthread_cond_broadcast. */
      case _VG_USERREQ__HG_PTHREAD_COND_SIGNAL_PRE:
      case _VG_USERREQ__HG_PTHREAD_COND_BROADCAST_PRE:
         HG_(thread_enter_synchr)(map_threads_maybe_lookup(tid));
         evh__HG_PTHREAD_COND_SIGNAL_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_COND_SIGNAL_POST:
      case _VG_USERREQ__HG_PTHREAD_COND_BROADCAST_POST:
         HG_(thread_leave_synchr)(map_threads_maybe_lookup(tid));
         break;

      /* Entry into pthread_cond_wait, cond=arg[1], mutex=arg[2].
         Returns a flag indicating whether or not the mutex is believed to be
         valid for this operation. */
      case _VG_USERREQ__HG_PTHREAD_COND_WAIT_PRE: {
         HG_(thread_enter_synchr)(map_threads_maybe_lookup(tid));
         Bool mutex_is_valid
            = evh__HG_PTHREAD_COND_WAIT_PRE( tid, (void*)args[1], 
                                                  (void*)args[2] );
         *ret = mutex_is_valid ? 1 : 0;
         break;
      }

      /* Thread successfully completed pthread_cond_init:
         cond=arg[1], cond_attr=arg[2] */
      case _VG_USERREQ__HG_PTHREAD_COND_INIT_POST:
         evh__HG_PTHREAD_COND_INIT_POST( tid,
                                         (void*)args[1], (void*)args[2] );
	 break;

      /* cond=arg[1], cond_is_init=arg[2] */
      case _VG_USERREQ__HG_PTHREAD_COND_DESTROY_PRE:
         evh__HG_PTHREAD_COND_DESTROY_PRE( tid, (void*)args[1], args[2] != 0 );
         break;

      /* Thread completed pthread_cond_wait, cond=arg[1],
         mutex=arg[2], timeout=arg[3], successful=arg[4] */
      case _VG_USERREQ__HG_PTHREAD_COND_WAIT_POST:
         if (args[4] == True)
            evh__HG_PTHREAD_COND_WAIT_POST( tid,
                                            (void*)args[1], (void*)args[2],
                                            (Bool)args[3] );
         HG_(thread_leave_synchr)(map_threads_maybe_lookup(tid));
         break;

      case _VG_USERREQ__HG_PTHREAD_RWLOCK_INIT_POST:
         evh__HG_PTHREAD_RWLOCK_INIT_POST( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_RWLOCK_DESTROY_PRE:
         evh__HG_PTHREAD_RWLOCK_DESTROY_PRE( tid, (void*)args[1] );
         break;

      /* rwlock=arg[1], isW=arg[2], isTryLock=arg[3] */
      case _VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE:
         HG_(thread_enter_synchr)(map_threads_maybe_lookup(tid));
         if (HG_(get_pthread_create_nesting_level)(tid) == 0)
            evh__HG_PTHREAD_RWLOCK_LOCK_PRE( tid, (void*)args[1],
                                             args[2], args[3] );
         break;

      /* rwlock=arg[1], isW=arg[2], tookLock=arg[3] */
      case _VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST:
         if ((args[3] == True)
             && (HG_(get_pthread_create_nesting_level)(tid) == 0))
            evh__HG_PTHREAD_RWLOCK_LOCK_POST( tid, (void*)args[1], args[2] );
         HG_(thread_leave_synchr)(map_threads_maybe_lookup(tid));
         break;

      case _VG_USERREQ__HG_PTHREAD_RWLOCK_UNLOCK_PRE:
         HG_(thread_enter_synchr)(map_threads_maybe_lookup(tid));
         if (HG_(get_pthread_create_nesting_level)(tid) == 0)
            evh__HG_PTHREAD_RWLOCK_UNLOCK_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_RWLOCK_UNLOCK_POST:
         if (HG_(get_pthread_create_nesting_level)(tid) == 0)
            evh__HG_PTHREAD_RWLOCK_UNLOCK_POST( tid, (void*)args[1] );
         HG_(thread_leave_synchr)(map_threads_maybe_lookup(tid));
         break;

      case _VG_USERREQ__HG_POSIX_SEM_INIT_POST: /* sem_t*, unsigned long */
         evh__HG_POSIX_SEM_INIT_POST( tid, (void*)args[1], args[2] );
         break;

      case _VG_USERREQ__HG_POSIX_SEM_DESTROY_PRE: /* sem_t* */
         evh__HG_POSIX_SEM_DESTROY_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_POSIX_SEM_POST_PRE: /* sem_t* */
         HG_(thread_enter_synchr)(map_threads_maybe_lookup(tid));
         evh__HG_POSIX_SEM_POST_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_POSIX_SEM_POST_POST: /* sem_t* */
         HG_(thread_leave_synchr)(map_threads_maybe_lookup(tid));
         break;

      case _VG_USERREQ__HG_POSIX_SEM_WAIT_PRE: /* sem_t* */
         HG_(thread_enter_synchr)(map_threads_maybe_lookup(tid));
         break;

      case _VG_USERREQ__HG_POSIX_SEM_WAIT_POST: /* sem_t*, long tookLock */
         if (args[2] == True)
            evh__HG_POSIX_SEM_WAIT_POST( tid, (void*)args[1] );
         HG_(thread_leave_synchr)(map_threads_maybe_lookup(tid));
         break;

      case _VG_USERREQ__HG_PTHREAD_BARRIER_INIT_PRE:
         /* pth_bar_t*, ulong count, ulong resizable */
         evh__HG_PTHREAD_BARRIER_INIT_PRE( tid, (void*)args[1],
                                                args[2], args[3] );
         break;

      case _VG_USERREQ__HG_PTHREAD_BARRIER_RESIZE_PRE:
         /* pth_bar_t*, ulong newcount */
         evh__HG_PTHREAD_BARRIER_RESIZE_PRE ( tid, (void*)args[1],
                                              args[2] );
         break;

      case _VG_USERREQ__HG_PTHREAD_BARRIER_WAIT_PRE:
         /* pth_bar_t* */
         evh__HG_PTHREAD_BARRIER_WAIT_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_BARRIER_DESTROY_PRE:
         /* pth_bar_t* */
         evh__HG_PTHREAD_BARRIER_DESTROY_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE:
         /* pth_spinlock_t* */
         evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_POST:
         /* pth_spinlock_t* */
         evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_POST( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_SPIN_LOCK_PRE:
         /* pth_spinlock_t*, Word */
         evh__HG_PTHREAD_SPIN_LOCK_PRE( tid, (void*)args[1], args[2] );
         break;

      case _VG_USERREQ__HG_PTHREAD_SPIN_LOCK_POST:
         /* pth_spinlock_t* */
         evh__HG_PTHREAD_SPIN_LOCK_POST( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_SPIN_DESTROY_PRE:
         /* pth_spinlock_t* */
         evh__HG_PTHREAD_SPIN_DESTROY_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_CLIENTREQ_UNIMP: {
         /* HChar* who */
         HChar*  who = (HChar*)args[1];
         HChar   buf[50 + 50];
         Thread* thr = map_threads_maybe_lookup( tid );
         tl_assert( thr ); /* I must be mapped */
         tl_assert( who );
         tl_assert( VG_(strlen)(who) <= 50 );
         VG_(sprintf)(buf, "Unimplemented client request macro \"%s\"", who );
         /* record_error_Misc strdup's buf, so this is safe: */
         HG_(record_error_Misc)( thr, buf );
         break;
      }

      case _VG_USERREQ__HG_USERSO_SEND_PRE:
         /* UWord arbitrary-SO-tag */
         evh__HG_USERSO_SEND_PRE( tid, args[1] );
         break;

      case _VG_USERREQ__HG_USERSO_RECV_POST:
         /* UWord arbitrary-SO-tag */
         evh__HG_USERSO_RECV_POST( tid, args[1] );
         break;

      case _VG_USERREQ__HG_USERSO_FORGET_ALL:
         /* UWord arbitrary-SO-tag */
         evh__HG_USERSO_FORGET_ALL( tid, args[1] );
         break;

      case VG_USERREQ__GDB_MONITOR_COMMAND: {
         Bool handled = handle_gdb_monitor_command (tid, (HChar*)args[1]);
         if (handled)
            *ret = 1;
         else
            *ret = 0;
         return handled;
      }

      case _VG_USERREQ__HG_PTHREAD_CREATE_BEGIN: {
         Thread *thr = map_threads_maybe_lookup(tid);
         if (HG_(clo_ignore_thread_creation)) {
            HG_(thread_enter_pthread_create)(thr);
            HG_(thread_enter_synchr)(thr);
         }
         break;
      }

      case _VG_USERREQ__HG_PTHREAD_CREATE_END: {
         Thread *thr = map_threads_maybe_lookup(tid);
         if (HG_(clo_ignore_thread_creation)) {
            HG_(thread_leave_pthread_create)(thr);
            HG_(thread_leave_synchr)(thr);
         }
         break;
      }

      case _VG_USERREQ__HG_PTHREAD_MUTEX_ACQUIRE_PRE: // pth_mx_t*, long tryLock
         evh__HG_PTHREAD_MUTEX_LOCK_PRE( tid, (void*)args[1], args[2] );
         break;

      case _VG_USERREQ__HG_PTHREAD_MUTEX_ACQUIRE_POST:    // pth_mx_t*
         evh__HG_PTHREAD_MUTEX_LOCK_POST( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_PTHREAD_RWLOCK_ACQUIRED:       // void*, long isW
         evh__HG_PTHREAD_RWLOCK_LOCK_POST( tid, (void*)args[1], args[2] );
         break;

      case _VG_USERREQ__HG_PTHREAD_RWLOCK_RELEASED:       // void*
         evh__HG_PTHREAD_RWLOCK_UNLOCK_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_POSIX_SEM_RELEASED: /* sem_t* */
         evh__HG_POSIX_SEM_POST_PRE( tid, (void*)args[1] );
         break;

      case _VG_USERREQ__HG_POSIX_SEM_ACQUIRED: /* sem_t* */
         evh__HG_POSIX_SEM_WAIT_POST( tid, (void*)args[1] );
         break;

#if defined(VGO_solaris)
      case _VG_USERREQ__HG_RTLD_BIND_GUARD:
         evh__HG_RTLD_BIND_GUARD(tid, args[1]);
         break;

      case _VG_USERREQ__HG_RTLD_BIND_CLEAR:
         evh__HG_RTLD_BIND_CLEAR(tid, args[1]);
         break;
#endif /* VGO_solaris */

      default:
         /* Unhandled Helgrind client request! */
         tl_assert2(0, "unhandled Helgrind client request 0x%lx",
                       args[0]);
   }

   return True;
}


/*----------------------------------------------------------------*/
/*--- Setup                                                    ---*/
/*----------------------------------------------------------------*/

static Bool hg_process_cmd_line_option ( const HChar* arg )
{
   const HChar* tmp_str;

   if      VG_BOOL_CLO(arg, "--track-lockorders",
                            HG_(clo_track_lockorders)) {}
   else if VG_BOOL_CLO(arg, "--cmp-race-err-addrs",
                            HG_(clo_cmp_race_err_addrs)) {}

   else if VG_XACT_CLO(arg, "--history-level=none",
                            HG_(clo_history_level), 0);
   else if VG_XACT_CLO(arg, "--history-level=approx",
                            HG_(clo_history_level), 1);
   else if VG_XACT_CLO(arg, "--history-level=full",
                            HG_(clo_history_level), 2);

   else if VG_BINT_CLO(arg, "--conflict-cache-size",
                       HG_(clo_conflict_cache_size), 10*1000, 150*1000*1000) {}

   /* "stuvwx" --> stuvwx (binary) */
   else if VG_STR_CLO(arg, "--hg-sanity-flags", tmp_str) {
      Int j;
   
      if (6 != VG_(strlen)(tmp_str)) {
         VG_(message)(Vg_UserMsg, 
                      "--hg-sanity-flags argument must have 6 digits\n");
         return False;
      }
      for (j = 0; j < 6; j++) {
         if      ('0' == tmp_str[j]) { /* do nothing */ }
         else if ('1' == tmp_str[j]) HG_(clo_sanity_flags) |= (1 << (6-1-j));
         else {
            VG_(message)(Vg_UserMsg, "--hg-sanity-flags argument can "
                                     "only contain 0s and 1s\n");
            return False;
         }
      }
      if (0) VG_(printf)("XXX sanity flags: 0x%lx\n", HG_(clo_sanity_flags));
   }

   else if VG_BOOL_CLO(arg, "--free-is-write",
                            HG_(clo_free_is_write)) {}

   else if VG_XACT_CLO(arg, "--vts-pruning=never",
                            HG_(clo_vts_pruning), 0);
   else if VG_XACT_CLO(arg, "--vts-pruning=auto",
                            HG_(clo_vts_pruning), 1);
   else if VG_XACT_CLO(arg, "--vts-pruning=always",
                            HG_(clo_vts_pruning), 2);

   else if VG_BOOL_CLO(arg, "--check-stack-refs",
                            HG_(clo_check_stack_refs)) {}
   else if VG_BOOL_CLO(arg, "--ignore-thread-creation",
                            HG_(clo_ignore_thread_creation)) {}

   else 
      return VG_(replacement_malloc_process_cmd_line_option)(arg);

   return True;
}

static void hg_print_usage ( void )
{
   VG_(printf)(
"    --free-is-write=no|yes    treat heap frees as writes [no]\n"
"    --track-lockorders=no|yes show lock ordering errors? [yes]\n"
"    --history-level=none|approx|full [full]\n"
"       full:   show both stack traces for a data race (can be very slow)\n"
"       approx: full trace for one thread, approx for the other (faster)\n"
"       none:   only show trace for one thread in a race (fastest)\n"
"    --conflict-cache-size=N   size of 'full' history cache [2000000]\n"
"    --check-stack-refs=no|yes race-check reads and writes on the\n"
"                              main stack and thread stacks? [yes]\n"
"    --ignore-thread-creation=yes|no Ignore activities during thread\n"
"                              creation [%s]\n",
HG_(clo_ignore_thread_creation) ? "yes" : "no"
   );
}

static void hg_print_debug_usage ( void )
{
   VG_(printf)("    --cmp-race-err-addrs=no|yes  are data addresses in "
               "race errors significant? [no]\n");
   VG_(printf)("    --hg-sanity-flags=<XXXXXX>   sanity check "
               "  at events (X = 0|1) [000000]\n");
   VG_(printf)("    --hg-sanity-flags values:\n");
   VG_(printf)("       010000   after changes to "
               "lock-order-acquisition-graph\n");
   VG_(printf)("       001000   at memory accesses (NB: not currently used)\n");
   VG_(printf)("       000100   at mem permission setting for "
               "ranges >= %d bytes\n", SCE_BIGRANGE_T);
   VG_(printf)("       000010   at lock/unlock events\n");
   VG_(printf)("       000001   at thread create/join events\n");
   VG_(printf)(
"    --vts-pruning=never|auto|always [auto]\n"
"       never:   is never done (may cause big space leaks in Helgrind)\n"
"       auto:    done just often enough to keep space usage under control\n"
"       always:  done after every VTS GC (mostly just a big time waster)\n"
    );
}

static void hg_print_stats (void)
{

   if (1) {
      VG_(printf)("\n");
      HG_(ppWSUstats)( univ_lsets, "univ_lsets" );
      if (HG_(clo_track_lockorders)) {
         VG_(printf)("\n");
         HG_(ppWSUstats)( univ_laog,  "univ_laog" );
      }
   }

   //zz       VG_(printf)("\n");
   //zz       VG_(printf)(" hbefore: %'10lu queries\n",        stats__hbefore_queries);
   //zz       VG_(printf)(" hbefore: %'10lu cache 0 hits\n",   stats__hbefore_cache0s);
   //zz       VG_(printf)(" hbefore: %'10lu cache > 0 hits\n", stats__hbefore_cacheNs);
   //zz       VG_(printf)(" hbefore: %'10lu graph searches\n", stats__hbefore_gsearches);
   //zz       VG_(printf)(" hbefore: %'10lu   of which slow\n",
   //zz                   stats__hbefore_gsearches - stats__hbefore_gsearchFs);
   //zz       VG_(printf)(" hbefore: %'10lu stack high water mark\n",
   //zz                   stats__hbefore_stk_hwm);
   //zz       VG_(printf)(" hbefore: %'10lu cache invals\n",   stats__hbefore_invals);
   //zz       VG_(printf)(" hbefore: %'10lu probes\n",         stats__hbefore_probes);

   VG_(printf)("\n");
   VG_(printf)("        locksets: %'8d unique lock sets\n",
               (Int)HG_(cardinalityWSU)( univ_lsets ));
   if (HG_(clo_track_lockorders)) {
      VG_(printf)("       univ_laog: %'8d unique lock sets\n",
                  (Int)HG_(cardinalityWSU)( univ_laog ));
   }

   //VG_(printf)("L(ast)L(ock) map: %'8lu inserts (%d map size)\n",
   //            stats__ga_LL_adds,
   //            (Int)(ga_to_lastlock ? VG_(sizeFM)( ga_to_lastlock ) : 0) );

   VG_(printf)("  LockN-to-P map: %'8llu queries (%llu map size)\n",
               HG_(stats__LockN_to_P_queries),
               HG_(stats__LockN_to_P_get_map_size)() );

   VG_(printf)("client malloc-ed blocks: %'8u\n",
               VG_(HT_count_nodes)(hg_mallocmeta_table));
               
   VG_(printf)("string table map: %'8llu queries (%llu map size)\n",
               HG_(stats__string_table_queries),
               HG_(stats__string_table_get_map_size)() );
   if (HG_(clo_track_lockorders)) {
      VG_(printf)("            LAOG: %'8d map size\n",
                  (Int)(laog ? VG_(sizeFM)( laog ) : 0));
      VG_(printf)(" LAOG exposition: %'8d map size\n",
                  (Int)(laog_exposition ? VG_(sizeFM)( laog_exposition ) : 0));
   }

   VG_(printf)("           locks: %'8lu acquires, "
               "%'lu releases\n",
               stats__lockN_acquires,
               stats__lockN_releases
              );
   VG_(printf)("   sanity checks: %'8lu\n", stats__sanity_checks);

   VG_(printf)("\n");
   libhb_shutdown(True); // This in fact only print stats.
}

static void hg_fini ( Int exitcode )
{
   if (VG_(clo_verbosity) == 1 && !VG_(clo_xml)) {
      VG_(message)(Vg_UserMsg, 
                   "For counts of detected and suppressed errors, "
                   "rerun with: -v\n");
   }

   if (VG_(clo_verbosity) == 1 && !VG_(clo_xml)
       && HG_(clo_history_level) >= 2) {
      VG_(umsg)( 
         "Use --history-level=approx or =none to gain increased speed, at\n" );
      VG_(umsg)(
         "the cost of reduced accuracy of conflicting-access information\n");
   }

   if (SHOW_DATA_STRUCTURES)
      pp_everything( PP_ALL, "SK_(fini)" );
   if (HG_(clo_sanity_flags))
      all__sanity_check("SK_(fini)");

   if (VG_(clo_stats))
      hg_print_stats();
}

/* FIXME: move these somewhere sane */

static
void for_libhb__get_stacktrace ( Thr* hbt, Addr* frames, UWord nRequest )
{
   Thread*     thr;
   ThreadId    tid;
   UWord       nActual;
   tl_assert(hbt);
   thr = libhb_get_Thr_hgthread( hbt );
   tl_assert(thr);
   tid = map_threads_maybe_reverse_lookup_SLOW(thr);
   nActual = (UWord)VG_(get_StackTrace)( tid, frames, (UInt)nRequest,
                                         NULL, NULL, 0 );
   tl_assert(nActual <= nRequest);
   for (; nActual < nRequest; nActual++)
      frames[nActual] = 0;
}

static
ExeContext* for_libhb__get_EC ( Thr* hbt )
{
   Thread*     thr;
   ThreadId    tid;
   ExeContext* ec;
   tl_assert(hbt);
   thr = libhb_get_Thr_hgthread( hbt );
   tl_assert(thr);
   tid = map_threads_maybe_reverse_lookup_SLOW(thr);
   /* this will assert if tid is invalid */
   ec = VG_(record_ExeContext)( tid, 0 );
   return ec;
}


static void hg_post_clo_init ( void )
{
   Thr* hbthr_root;

   /////////////////////////////////////////////
   hbthr_root = libhb_init( for_libhb__get_stacktrace, 
                            for_libhb__get_EC );
   /////////////////////////////////////////////


   if (HG_(clo_track_lockorders))
      laog__init();

   initialise_data_structures(hbthr_root);
}

static void hg_info_location (Addr a)
{
   (void) HG_(get_and_pp_addrdescr) (a);
}

static void hg_pre_clo_init ( void )
{
   VG_(details_name)            ("Helgrind");
   VG_(details_version)         (NULL);
   VG_(details_description)     ("a thread error detector");
   VG_(details_copyright_author)(
      "Copyright (C) 2007-2015, and GNU GPL'd, by OpenWorks LLP et al.");
   VG_(details_bug_reports_to)  (VG_BUGS_TO);
   VG_(details_avg_translation_sizeB) ( 320 );

   VG_(basic_tool_funcs)          (hg_post_clo_init,
                                   hg_instrument,
                                   hg_fini);

   VG_(needs_core_errors)         ();
   VG_(needs_tool_errors)         (HG_(eq_Error),
                                   HG_(before_pp_Error),
                                   HG_(pp_Error),
                                   False,/*show TIDs for errors*/
                                   HG_(update_extra),
                                   HG_(recognised_suppression),
                                   HG_(read_extra_suppression_info),
                                   HG_(error_matches_suppression),
                                   HG_(get_error_name),
                                   HG_(get_extra_suppression_info),
                                   HG_(print_extra_suppression_use),
                                   HG_(update_extra_suppression_use));

   VG_(needs_xml_output)          ();

   VG_(needs_command_line_options)(hg_process_cmd_line_option,
                                   hg_print_usage,
                                   hg_print_debug_usage);
   VG_(needs_client_requests)     (hg_handle_client_request);

   // FIXME?
   //VG_(needs_sanity_checks)       (hg_cheap_sanity_check,
   //                                hg_expensive_sanity_check);

   VG_(needs_print_stats) (hg_print_stats);
   VG_(needs_info_location) (hg_info_location);

   VG_(needs_malloc_replacement)  (hg_cli__malloc,
                                   hg_cli____builtin_new,
                                   hg_cli____builtin_vec_new,
                                   hg_cli__memalign,
                                   hg_cli__calloc,
                                   hg_cli__free,
                                   hg_cli____builtin_delete,
                                   hg_cli____builtin_vec_delete,
                                   hg_cli__realloc,
                                   hg_cli_malloc_usable_size,
                                   HG_CLI__DEFAULT_MALLOC_REDZONE_SZB );

   /* 21 Dec 08: disabled this; it mostly causes H to start more
      slowly and use significantly more memory, without very often
      providing useful results.  The user can request to load this
      information manually with --read-var-info=yes. */
   if (0) VG_(needs_var_info)(); /* optional */

   VG_(track_new_mem_startup)     ( evh__new_mem_w_perms );
   VG_(track_new_mem_stack_signal)( evh__new_mem_w_tid );
   VG_(track_new_mem_brk)         ( evh__new_mem_w_tid );
   VG_(track_new_mem_mmap)        ( evh__new_mem_w_perms );
   VG_(track_new_mem_stack)       ( evh__new_mem_stack );

   // FIXME: surely this isn't thread-aware
   VG_(track_copy_mem_remap)      ( evh__copy_mem );

   VG_(track_change_mem_mprotect) ( evh__set_perms );

   VG_(track_die_mem_stack_signal)( evh__die_mem );
   VG_(track_die_mem_brk)         ( evh__die_mem_munmap );
   VG_(track_die_mem_munmap)      ( evh__die_mem_munmap );

   /* evh__die_mem calls at the end libhb_srange_noaccess_NoFX
      which has no effect. We do not use  VG_(track_die_mem_stack),
      as this would be an expensive way to do nothing. */      
   // VG_(track_die_mem_stack)       ( evh__die_mem );

   // FIXME: what is this for?
   VG_(track_ban_mem_stack)       (NULL);

   VG_(track_pre_mem_read)        ( evh__pre_mem_read );
   VG_(track_pre_mem_read_asciiz) ( evh__pre_mem_read_asciiz );
   VG_(track_pre_mem_write)       ( evh__pre_mem_write );
   VG_(track_post_mem_write)      (NULL);

   /////////////////

   VG_(track_pre_thread_ll_create)( evh__pre_thread_ll_create );
   VG_(track_pre_thread_ll_exit)  ( evh__pre_thread_ll_exit );

   VG_(track_start_client_code)( evh__start_client_code );
   VG_(track_stop_client_code)( evh__stop_client_code );

   /* Ensure that requirements for "dodgy C-as-C++ style inheritance"
      as described in comments at the top of pub_tool_hashtable.h, are
      met.  Blargh. */
   tl_assert( sizeof(void*) == sizeof(struct _MallocMeta*) );
   tl_assert( sizeof(UWord) == sizeof(Addr) );
   hg_mallocmeta_table
      = VG_(HT_construct)( "hg_malloc_metadata_table" );

   MallocMeta_poolalloc = VG_(newPA) ( sizeof(MallocMeta),
                                       1000,
                                       HG_(zalloc),
                                       "hg_malloc_metadata_pool",
                                       HG_(free));

   // add a callback to clean up on (threaded) fork.
   VG_(atfork)(NULL/*pre*/, NULL/*parent*/, evh__atfork_child/*child*/);
}

VG_DETERMINE_INTERFACE_VERSION(hg_pre_clo_init)

/*--------------------------------------------------------------------*/
/*--- end                                                hg_main.c ---*/
/*--------------------------------------------------------------------*/
