1
2/*--------------------------------------------------------------------*/
3/*--- Helgrind: a Valgrind tool for detecting errors               ---*/
4/*--- in threaded programs.                              hg_main.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8   This file is part of Helgrind, a Valgrind tool for detecting errors
9   in threaded programs.
10
11   Copyright (C) 2007-2013 OpenWorks LLP
12      info@open-works.co.uk
13
14   Copyright (C) 2007-2013 Apple, Inc.
15
16   This program is free software; you can redistribute it and/or
17   modify it under the terms of the GNU General Public License as
18   published by the Free Software Foundation; either version 2 of the
19   License, or (at your option) any later version.
20
21   This program is distributed in the hope that it will be useful, but
22   WITHOUT ANY WARRANTY; without even the implied warranty of
23   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   General Public License for more details.
25
26   You should have received a copy of the GNU General Public License
27   along with this program; if not, write to the Free Software
28   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29   02111-1307, USA.
30
31   The GNU General Public License is contained in the file COPYING.
32
33   Neither the names of the U.S. Department of Energy nor the
34   University of California nor the names of its contributors may be
35   used to endorse or promote products derived from this software
36   without prior written permission.
37*/
38
39#include "pub_tool_basics.h"
40#include "pub_tool_gdbserver.h"
41#include "pub_tool_libcassert.h"
42#include "pub_tool_libcbase.h"
43#include "pub_tool_libcprint.h"
44#include "pub_tool_threadstate.h"
45#include "pub_tool_tooliface.h"
46#include "pub_tool_hashtable.h"
47#include "pub_tool_replacemalloc.h"
48#include "pub_tool_machine.h"
49#include "pub_tool_options.h"
50#include "pub_tool_xarray.h"
51#include "pub_tool_stacktrace.h"
52#include "pub_tool_wordfm.h"
53#include "pub_tool_debuginfo.h" // VG_(find_seginfo), VG_(seginfo_soname)
54#include "pub_tool_redir.h"     // sonames for the dynamic linkers
55#include "pub_tool_vki.h"       // VKI_PAGE_SIZE
56#include "pub_tool_libcproc.h"  // VG_(atfork)
57#include "pub_tool_aspacemgr.h" // VG_(am_is_valid_for_client)
58#include "pub_tool_poolalloc.h"
59#include "pub_tool_addrinfo.h"
60
61#include "hg_basics.h"
62#include "hg_wordset.h"
63#include "hg_addrdescr.h"
64#include "hg_lock_n_thread.h"
65#include "hg_errors.h"
66
67#include "libhb.h"
68
69#include "helgrind.h"
70
71
72// FIXME: new_mem_w_tid ignores the supplied tid. (wtf?!)
73
74// FIXME: when client destroys a lock or a CV, remove these
75// from our mappings, so that the associated SO can be freed up
76
77/*----------------------------------------------------------------*/
78/*---                                                          ---*/
79/*----------------------------------------------------------------*/
80
81/* Note this needs to be compiled with -fno-strict-aliasing, since it
82   contains a whole bunch of calls to lookupFM etc which cast between
83   Word and pointer types.  gcc rightly complains this breaks ANSI C
84   strict aliasing rules, at -O2.  No complaints at -O, but -O2 gives
85   worthwhile performance benefits over -O.
86*/
87
88// FIXME what is supposed to happen to locks in memory which
89// is relocated as a result of client realloc?
90
91// FIXME put referencing ThreadId into Thread and get
92// rid of the slow reverse mapping function.
93
94// FIXME accesses to NoAccess areas: change state to Excl?
95
96// FIXME report errors for accesses of NoAccess memory?
97
98// FIXME pth_cond_wait/timedwait wrappers.  Even if these fail,
99// the thread still holds the lock.
100
101/* ------------ Debug/trace options ------------ */
102
103// 0 for silent, 1 for some stuff, 2 for lots of stuff
104#define SHOW_EVENTS 0
105
106
107static void all__sanity_check ( const HChar* who ); /* fwds */
108
109#define HG_CLI__DEFAULT_MALLOC_REDZONE_SZB 16 /* let's say */
110
111// 0 for none, 1 for dump at end of run
112#define SHOW_DATA_STRUCTURES 0
113
114
115/* ------------ Misc comments ------------ */
116
117// FIXME: don't hardwire initial entries for root thread.
118// Instead, let the pre_thread_ll_create handler do this.
119
120
121/*----------------------------------------------------------------*/
122/*--- Primary data structures                                  ---*/
123/*----------------------------------------------------------------*/
124
125/* Admin linked list of Threads */
126static Thread* admin_threads = NULL;
127Thread* get_admin_threads ( void ) { return admin_threads; }
128
129/* Admin double linked list of Locks */
130/* We need a double linked list to properly and efficiently
131   handle del_LockN. */
132static Lock* admin_locks = NULL;
133
134/* Mapping table for core ThreadIds to Thread* */
135static Thread** map_threads = NULL; /* Array[VG_N_THREADS] of Thread* */
136
137/* Mapping table for lock guest addresses to Lock* */
138static WordFM* map_locks = NULL; /* WordFM LockAddr Lock* */
139
140/* The word-set universes for lock sets. */
141static WordSetU* univ_lsets = NULL; /* sets of Lock* */
142static WordSetU* univ_laog  = NULL; /* sets of Lock*, for LAOG */
143static Int next_gc_univ_laog = 1;
144/* univ_laog will be garbaged collected when the nr of element in univ_laog is
145   >= next_gc_univ_laog. */
146
147/* Allow libhb to get at the universe of locksets stored
148   here.  Sigh. */
149WordSetU* HG_(get_univ_lsets) ( void ) { return univ_lsets; }
150
151/* Allow libhb to get at the list of locks stored here.  Ditto
152   sigh. */
153Lock* HG_(get_admin_locks) ( void ) { return admin_locks; }
154
155
156/*----------------------------------------------------------------*/
157/*--- Simple helpers for the data structures                   ---*/
158/*----------------------------------------------------------------*/
159
160static UWord stats__lockN_acquires = 0;
161static UWord stats__lockN_releases = 0;
162
163static
164ThreadId map_threads_maybe_reverse_lookup_SLOW ( Thread* thr ); /*fwds*/
165
166/* --------- Constructors --------- */
167
168static Thread* mk_Thread ( Thr* hbthr ) {
169   static Int indx      = 1;
170   Thread* thread       = HG_(zalloc)( "hg.mk_Thread.1", sizeof(Thread) );
171   thread->locksetA     = HG_(emptyWS)( univ_lsets );
172   thread->locksetW     = HG_(emptyWS)( univ_lsets );
173   thread->magic        = Thread_MAGIC;
174   thread->hbthr        = hbthr;
175   thread->coretid      = VG_INVALID_THREADID;
176   thread->created_at   = NULL;
177   thread->announced    = False;
178   thread->errmsg_index = indx++;
179   thread->admin        = admin_threads;
180   admin_threads        = thread;
181   return thread;
182}
183
184// Make a new lock which is unlocked (hence ownerless)
185// and insert the new lock in admin_locks double linked list.
186static Lock* mk_LockN ( LockKind kind, Addr guestaddr ) {
187   static ULong unique = 0;
188   Lock* lock             = HG_(zalloc)( "hg.mk_Lock.1", sizeof(Lock) );
189   /* begin: add to double linked list */
190   if (admin_locks)
191      admin_locks->admin_prev = lock;
192   lock->admin_next       = admin_locks;
193   lock->admin_prev       = NULL;
194   admin_locks            = lock;
195   /* end: add */
196   lock->unique           = unique++;
197   lock->magic            = LockN_MAGIC;
198   lock->appeared_at      = NULL;
199   lock->acquired_at      = NULL;
200   lock->hbso             = libhb_so_alloc();
201   lock->guestaddr        = guestaddr;
202   lock->kind             = kind;
203   lock->heldW            = False;
204   lock->heldBy           = NULL;
205   tl_assert(HG_(is_sane_LockN)(lock));
206   return lock;
207}
208
209/* Release storage for a Lock.  Also release storage in .heldBy, if
210   any. Removes from admin_locks double linked list. */
211static void del_LockN ( Lock* lk )
212{
213   tl_assert(HG_(is_sane_LockN)(lk));
214   tl_assert(lk->hbso);
215   libhb_so_dealloc(lk->hbso);
216   if (lk->heldBy)
217      VG_(deleteBag)( lk->heldBy );
218   /* begin: del lock from double linked list */
219   if (lk == admin_locks) {
220      tl_assert(lk->admin_prev == NULL);
221      if (lk->admin_next)
222         lk->admin_next->admin_prev = NULL;
223      admin_locks = lk->admin_next;
224   }
225   else {
226      tl_assert(lk->admin_prev != NULL);
227      lk->admin_prev->admin_next = lk->admin_next;
228      if (lk->admin_next)
229         lk->admin_next->admin_prev = lk->admin_prev;
230   }
231   /* end: del */
232   VG_(memset)(lk, 0xAA, sizeof(*lk));
233   HG_(free)(lk);
234}
235
236/* Update 'lk' to reflect that 'thr' now has a write-acquisition of
237   it.  This is done strictly: only combinations resulting from
238   correct program and libpthread behaviour are allowed. */
239static void lockN_acquire_writer ( Lock* lk, Thread* thr )
240{
241   tl_assert(HG_(is_sane_LockN)(lk));
242   tl_assert(HG_(is_sane_Thread)(thr));
243
244   stats__lockN_acquires++;
245
246   /* EXPOSITION only */
247   /* We need to keep recording snapshots of where the lock was
248      acquired, so as to produce better lock-order error messages. */
249   if (lk->acquired_at == NULL) {
250      ThreadId tid;
251      tl_assert(lk->heldBy == NULL);
252      tid = map_threads_maybe_reverse_lookup_SLOW(thr);
253      lk->acquired_at
254         = VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
255   } else {
256      tl_assert(lk->heldBy != NULL);
257   }
258   /* end EXPOSITION only */
259
260   switch (lk->kind) {
261      case LK_nonRec:
262      case_LK_nonRec:
263         tl_assert(lk->heldBy == NULL); /* can't w-lock recursively */
264         tl_assert(!lk->heldW);
265         lk->heldW  = True;
266         lk->heldBy = VG_(newBag)( HG_(zalloc), "hg.lNaw.1", HG_(free) );
267         VG_(addToBag)( lk->heldBy, (UWord)thr );
268         break;
269      case LK_mbRec:
270         if (lk->heldBy == NULL)
271            goto case_LK_nonRec;
272         /* 2nd and subsequent locking of a lock by its owner */
273         tl_assert(lk->heldW);
274         /* assert: lk is only held by one thread .. */
275         tl_assert(VG_(sizeUniqueBag(lk->heldBy)) == 1);
276         /* assert: .. and that thread is 'thr'. */
277         tl_assert(VG_(elemBag)(lk->heldBy, (UWord)thr)
278                   == VG_(sizeTotalBag)(lk->heldBy));
279         VG_(addToBag)(lk->heldBy, (UWord)thr);
280         break;
281      case LK_rdwr:
282         tl_assert(lk->heldBy == NULL && !lk->heldW); /* must be unheld */
283         goto case_LK_nonRec;
284      default:
285         tl_assert(0);
286  }
287  tl_assert(HG_(is_sane_LockN)(lk));
288}
289
290static void lockN_acquire_reader ( Lock* lk, Thread* thr )
291{
292   tl_assert(HG_(is_sane_LockN)(lk));
293   tl_assert(HG_(is_sane_Thread)(thr));
294   /* can only add reader to a reader-writer lock. */
295   tl_assert(lk->kind == LK_rdwr);
296   /* lk must be free or already r-held. */
297   tl_assert(lk->heldBy == NULL
298             || (lk->heldBy != NULL && !lk->heldW));
299
300   stats__lockN_acquires++;
301
302   /* EXPOSITION only */
303   /* We need to keep recording snapshots of where the lock was
304      acquired, so as to produce better lock-order error messages. */
305   if (lk->acquired_at == NULL) {
306      ThreadId tid;
307      tl_assert(lk->heldBy == NULL);
308      tid = map_threads_maybe_reverse_lookup_SLOW(thr);
309      lk->acquired_at
310         = VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
311   } else {
312      tl_assert(lk->heldBy != NULL);
313   }
314   /* end EXPOSITION only */
315
316   if (lk->heldBy) {
317      VG_(addToBag)(lk->heldBy, (UWord)thr);
318   } else {
319      lk->heldW  = False;
320      lk->heldBy = VG_(newBag)( HG_(zalloc), "hg.lNar.1", HG_(free) );
321      VG_(addToBag)( lk->heldBy, (UWord)thr );
322   }
323   tl_assert(!lk->heldW);
324   tl_assert(HG_(is_sane_LockN)(lk));
325}
326
327/* Update 'lk' to reflect a release of it by 'thr'.  This is done
328   strictly: only combinations resulting from correct program and
329   libpthread behaviour are allowed. */
330
331static void lockN_release ( Lock* lk, Thread* thr )
332{
333   Bool b;
334   tl_assert(HG_(is_sane_LockN)(lk));
335   tl_assert(HG_(is_sane_Thread)(thr));
336   /* lock must be held by someone */
337   tl_assert(lk->heldBy);
338   stats__lockN_releases++;
339   /* Remove it from the holder set */
340   b = VG_(delFromBag)(lk->heldBy, (UWord)thr);
341   /* thr must actually have been a holder of lk */
342   tl_assert(b);
343   /* normalise */
344   tl_assert(lk->acquired_at);
345   if (VG_(isEmptyBag)(lk->heldBy)) {
346      VG_(deleteBag)(lk->heldBy);
347      lk->heldBy      = NULL;
348      lk->heldW       = False;
349      lk->acquired_at = NULL;
350   }
351   tl_assert(HG_(is_sane_LockN)(lk));
352}
353
354static void remove_Lock_from_locksets_of_all_owning_Threads( Lock* lk )
355{
356   Thread* thr;
357   if (!lk->heldBy) {
358      tl_assert(!lk->heldW);
359      return;
360   }
361   /* for each thread that holds this lock do ... */
362   VG_(initIterBag)( lk->heldBy );
363   while (VG_(nextIterBag)( lk->heldBy, (UWord*)&thr, NULL )) {
364      tl_assert(HG_(is_sane_Thread)(thr));
365      tl_assert(HG_(elemWS)( univ_lsets,
366                             thr->locksetA, (UWord)lk ));
367      thr->locksetA
368         = HG_(delFromWS)( univ_lsets, thr->locksetA, (UWord)lk );
369
370      if (lk->heldW) {
371         tl_assert(HG_(elemWS)( univ_lsets,
372                                thr->locksetW, (UWord)lk ));
373         thr->locksetW
374            = HG_(delFromWS)( univ_lsets, thr->locksetW, (UWord)lk );
375      }
376   }
377   VG_(doneIterBag)( lk->heldBy );
378}
379
380
381/*----------------------------------------------------------------*/
382/*--- Print out the primary data structures                    ---*/
383/*----------------------------------------------------------------*/
384
385#define PP_THREADS      (1<<1)
386#define PP_LOCKS        (1<<2)
387#define PP_ALL (PP_THREADS | PP_LOCKS)
388
389
390static const Int sHOW_ADMIN = 0;
391
392static void space ( Int n )
393{
394   Int  i;
395   HChar spaces[128+1];
396   tl_assert(n >= 0 && n < 128);
397   if (n == 0)
398      return;
399   for (i = 0; i < n; i++)
400      spaces[i] = ' ';
401   spaces[i] = 0;
402   tl_assert(i < 128+1);
403   VG_(printf)("%s", spaces);
404}
405
406static void pp_Thread ( Int d, Thread* t )
407{
408   space(d+0); VG_(printf)("Thread %p {\n", t);
409   if (sHOW_ADMIN) {
410   space(d+3); VG_(printf)("admin    %p\n",   t->admin);
411   space(d+3); VG_(printf)("magic    0x%x\n", (UInt)t->magic);
412   }
413   space(d+3); VG_(printf)("locksetA %d\n",   (Int)t->locksetA);
414   space(d+3); VG_(printf)("locksetW %d\n",   (Int)t->locksetW);
415   space(d+0); VG_(printf)("}\n");
416}
417
418static void pp_admin_threads ( Int d )
419{
420   Int     i, n;
421   Thread* t;
422   for (n = 0, t = admin_threads;  t;  n++, t = t->admin) {
423      /* nothing */
424   }
425   space(d); VG_(printf)("admin_threads (%d records) {\n", n);
426   for (i = 0, t = admin_threads;  t;  i++, t = t->admin) {
427      if (0) {
428         space(n);
429         VG_(printf)("admin_threads record %d of %d:\n", i, n);
430      }
431      pp_Thread(d+3, t);
432   }
433   space(d); VG_(printf)("}\n");
434}
435
436static void pp_map_threads ( Int d )
437{
438   Int i, n = 0;
439   space(d); VG_(printf)("map_threads ");
440   for (i = 0; i < VG_N_THREADS; i++) {
441      if (map_threads[i] != NULL)
442         n++;
443   }
444   VG_(printf)("(%d entries) {\n", n);
445   for (i = 0; i < VG_N_THREADS; i++) {
446      if (map_threads[i] == NULL)
447         continue;
448      space(d+3);
449      VG_(printf)("coretid %d -> Thread %p\n", i, map_threads[i]);
450   }
451   space(d); VG_(printf)("}\n");
452}
453
454static const HChar* show_LockKind ( LockKind lkk ) {
455   switch (lkk) {
456      case LK_mbRec:  return "mbRec";
457      case LK_nonRec: return "nonRec";
458      case LK_rdwr:   return "rdwr";
459      default:        tl_assert(0);
460   }
461}
462
463/* Pretty Print lock lk.
464   if show_lock_addrdescr, describes the (guest) lock address.
465     (this description will be more complete with --read-var-info=yes).
466   if show_internal_data, shows also helgrind internal information.
467   d is the level at which output is indented. */
468static void pp_Lock ( Int d, Lock* lk,
469                      Bool show_lock_addrdescr,
470                      Bool show_internal_data)
471{
472   space(d+0);
473   if (show_internal_data)
474      VG_(printf)("Lock %p (ga %#lx) {\n", lk, lk->guestaddr);
475   else
476      VG_(printf)("Lock ga %#lx {\n", lk->guestaddr);
477   if (!show_lock_addrdescr
478       || !HG_(get_and_pp_addrdescr) ((Addr) lk->guestaddr))
479      VG_(printf)("\n");
480
481   if (sHOW_ADMIN) {
482      space(d+3); VG_(printf)("admin_n  %p\n",   lk->admin_next);
483      space(d+3); VG_(printf)("admin_p  %p\n",   lk->admin_prev);
484      space(d+3); VG_(printf)("magic    0x%x\n", (UInt)lk->magic);
485   }
486   if (show_internal_data) {
487      space(d+3); VG_(printf)("unique %llu\n", lk->unique);
488   }
489   space(d+3); VG_(printf)("kind   %s\n", show_LockKind(lk->kind));
490   if (show_internal_data) {
491      space(d+3); VG_(printf)("heldW  %s\n", lk->heldW ? "yes" : "no");
492   }
493   if (show_internal_data) {
494      space(d+3); VG_(printf)("heldBy %p", lk->heldBy);
495   }
496   if (lk->heldBy) {
497      Thread* thr;
498      UWord   count;
499      VG_(printf)(" { ");
500      VG_(initIterBag)( lk->heldBy );
501      while (VG_(nextIterBag)( lk->heldBy, (UWord*)&thr, &count )) {
502         if (show_internal_data)
503            VG_(printf)("%lu:%p ", count, thr);
504         else {
505            VG_(printf)("%c%lu:thread #%d ",
506                        lk->heldW ? 'W' : 'R',
507                        count, thr->errmsg_index);
508            if (thr->coretid == VG_INVALID_THREADID)
509               VG_(printf)("tid (exited) ");
510            else
511               VG_(printf)("tid %d ", thr->coretid);
512
513         }
514      }
515      VG_(doneIterBag)( lk->heldBy );
516      VG_(printf)("}\n");
517   }
518   space(d+0); VG_(printf)("}\n");
519}
520
521static void pp_admin_locks ( Int d )
522{
523   Int   i, n;
524   Lock* lk;
525   for (n = 0, lk = admin_locks;  lk;  n++, lk = lk->admin_next) {
526      /* nothing */
527   }
528   space(d); VG_(printf)("admin_locks (%d records) {\n", n);
529   for (i = 0, lk = admin_locks;  lk;  i++, lk = lk->admin_next) {
530      if (0) {
531         space(n);
532         VG_(printf)("admin_locks record %d of %d:\n", i, n);
533      }
534      pp_Lock(d+3, lk,
535              False /* show_lock_addrdescr */,
536              True /* show_internal_data */);
537   }
538   space(d); VG_(printf)("}\n");
539}
540
541static void pp_map_locks ( Int d)
542{
543   void* gla;
544   Lock* lk;
545   space(d); VG_(printf)("map_locks (%d entries) {\n",
546                         (Int)VG_(sizeFM)( map_locks ));
547   VG_(initIterFM)( map_locks );
548   while (VG_(nextIterFM)( map_locks, (UWord*)&gla,
549                                      (UWord*)&lk )) {
550      space(d+3);
551      VG_(printf)("guest %p -> Lock %p\n", gla, lk);
552   }
553   VG_(doneIterFM)( map_locks );
554   space(d); VG_(printf)("}\n");
555}
556
557static void pp_everything ( Int flags, const HChar* caller )
558{
559   Int d = 0;
560   VG_(printf)("\n");
561   VG_(printf)("All_Data_Structures (caller = \"%s\") {\n", caller);
562   if (flags & PP_THREADS) {
563      VG_(printf)("\n");
564      pp_admin_threads(d+3);
565      VG_(printf)("\n");
566      pp_map_threads(d+3);
567   }
568   if (flags & PP_LOCKS) {
569      VG_(printf)("\n");
570      pp_admin_locks(d+3);
571      VG_(printf)("\n");
572      pp_map_locks(d+3);
573   }
574
575   VG_(printf)("\n");
576   VG_(printf)("}\n");
577   VG_(printf)("\n");
578}
579
580#undef SHOW_ADMIN
581
582
583/*----------------------------------------------------------------*/
584/*--- Initialise the primary data structures                   ---*/
585/*----------------------------------------------------------------*/
586
587static void initialise_data_structures ( Thr* hbthr_root )
588{
589   Thread*   thr;
590   WordSetID wsid;
591
592   /* Get everything initialised and zeroed. */
593   tl_assert(admin_threads == NULL);
594   tl_assert(admin_locks == NULL);
595
596   tl_assert(map_threads == NULL);
597   map_threads = HG_(zalloc)( "hg.ids.1", VG_N_THREADS * sizeof(Thread*) );
598   tl_assert(map_threads != NULL);
599
600   tl_assert(sizeof(Addr) == sizeof(UWord));
601   tl_assert(map_locks == NULL);
602   map_locks = VG_(newFM)( HG_(zalloc), "hg.ids.2", HG_(free),
603                           NULL/*unboxed Word cmp*/);
604   tl_assert(map_locks != NULL);
605
606   tl_assert(univ_lsets == NULL);
607   univ_lsets = HG_(newWordSetU)( HG_(zalloc), "hg.ids.4", HG_(free),
608                                  8/*cacheSize*/ );
609   tl_assert(univ_lsets != NULL);
610   /* Ensure that univ_lsets is non-empty, with lockset zero being the
611      empty lockset.  hg_errors.c relies on the assumption that
612      lockset number zero in univ_lsets is always valid. */
613   wsid = HG_(emptyWS)(univ_lsets);
614   tl_assert(wsid == 0);
615
616   tl_assert(univ_laog == NULL);
617   if (HG_(clo_track_lockorders)) {
618      univ_laog = HG_(newWordSetU)( HG_(zalloc), "hg.ids.5 (univ_laog)",
619                                    HG_(free), 24/*cacheSize*/ );
620      tl_assert(univ_laog != NULL);
621   }
622
623   /* Set up entries for the root thread */
624   // FIXME: this assumes that the first real ThreadId is 1
625
626   /* a Thread for the new thread ... */
627   thr = mk_Thread(hbthr_root);
628   thr->coretid = 1; /* FIXME: hardwires an assumption about the
629                        identity of the root thread. */
630   tl_assert( libhb_get_Thr_hgthread(hbthr_root) == NULL );
631   libhb_set_Thr_hgthread(hbthr_root, thr);
632
633   /* and bind it in the thread-map table. */
634   tl_assert(HG_(is_sane_ThreadId)(thr->coretid));
635   tl_assert(thr->coretid != VG_INVALID_THREADID);
636
637   map_threads[thr->coretid] = thr;
638
639   tl_assert(VG_INVALID_THREADID == 0);
640
641   all__sanity_check("initialise_data_structures");
642}
643
644
645/*----------------------------------------------------------------*/
646/*--- map_threads :: array[core-ThreadId] of Thread*           ---*/
647/*----------------------------------------------------------------*/
648
649/* Doesn't assert if the relevant map_threads entry is NULL. */
650static Thread* map_threads_maybe_lookup ( ThreadId coretid )
651{
652   Thread* thr;
653   tl_assert( HG_(is_sane_ThreadId)(coretid) );
654   thr = map_threads[coretid];
655   return thr;
656}
657
658/* Asserts if the relevant map_threads entry is NULL. */
659static inline Thread* map_threads_lookup ( ThreadId coretid )
660{
661   Thread* thr;
662   tl_assert( HG_(is_sane_ThreadId)(coretid) );
663   thr = map_threads[coretid];
664   tl_assert(thr);
665   return thr;
666}
667
668/* Do a reverse lookup.  Does not assert if 'thr' is not found in
669   map_threads. */
670static ThreadId map_threads_maybe_reverse_lookup_SLOW ( Thread* thr )
671{
672   ThreadId tid;
673   tl_assert(HG_(is_sane_Thread)(thr));
674   /* Check nobody used the invalid-threadid slot */
675   tl_assert(VG_INVALID_THREADID >= 0 && VG_INVALID_THREADID < VG_N_THREADS);
676   tl_assert(map_threads[VG_INVALID_THREADID] == NULL);
677   tid = thr->coretid;
678   tl_assert(HG_(is_sane_ThreadId)(tid));
679   return tid;
680}
681
682/* Do a reverse lookup.  Warning: POTENTIALLY SLOW.  Asserts if 'thr'
683   is not found in map_threads. */
684static ThreadId map_threads_reverse_lookup_SLOW ( Thread* thr )
685{
686   ThreadId tid = map_threads_maybe_reverse_lookup_SLOW( thr );
687   tl_assert(tid != VG_INVALID_THREADID);
688   tl_assert(map_threads[tid]);
689   tl_assert(map_threads[tid]->coretid == tid);
690   return tid;
691}
692
693static void map_threads_delete ( ThreadId coretid )
694{
695   Thread* thr;
696   tl_assert(coretid != 0);
697   tl_assert( HG_(is_sane_ThreadId)(coretid) );
698   thr = map_threads[coretid];
699   tl_assert(thr);
700   map_threads[coretid] = NULL;
701}
702
703
704/*----------------------------------------------------------------*/
705/*--- map_locks :: WordFM guest-Addr-of-lock Lock*             ---*/
706/*----------------------------------------------------------------*/
707
708/* Make sure there is a lock table entry for the given (lock) guest
709   address.  If not, create one of the stated 'kind' in unheld state.
710   In any case, return the address of the existing or new Lock. */
711static
712Lock* map_locks_lookup_or_create ( LockKind lkk, Addr ga, ThreadId tid )
713{
714   Bool  found;
715   Lock* oldlock = NULL;
716   tl_assert(HG_(is_sane_ThreadId)(tid));
717   found = VG_(lookupFM)( map_locks,
718                          NULL, (UWord*)&oldlock, (UWord)ga );
719   if (!found) {
720      Lock* lock = mk_LockN(lkk, ga);
721      lock->appeared_at = VG_(record_ExeContext)( tid, 0 );
722      tl_assert(HG_(is_sane_LockN)(lock));
723      VG_(addToFM)( map_locks, (UWord)ga, (UWord)lock );
724      tl_assert(oldlock == NULL);
725      return lock;
726   } else {
727      tl_assert(oldlock != NULL);
728      tl_assert(HG_(is_sane_LockN)(oldlock));
729      tl_assert(oldlock->guestaddr == ga);
730      return oldlock;
731   }
732}
733
734static Lock* map_locks_maybe_lookup ( Addr ga )
735{
736   Bool  found;
737   Lock* lk = NULL;
738   found = VG_(lookupFM)( map_locks, NULL, (UWord*)&lk, (UWord)ga );
739   tl_assert(found  ?  lk != NULL  :  lk == NULL);
740   return lk;
741}
742
743static void map_locks_delete ( Addr ga )
744{
745   Addr  ga2 = 0;
746   Lock* lk  = NULL;
747   VG_(delFromFM)( map_locks,
748                   (UWord*)&ga2, (UWord*)&lk, (UWord)ga );
749   /* delFromFM produces the val which is being deleted, if it is
750      found.  So assert it is non-null; that in effect asserts that we
751      are deleting a (ga, Lock) pair which actually exists. */
752   tl_assert(lk != NULL);
753   tl_assert(ga2 == ga);
754}
755
756
757
758/*----------------------------------------------------------------*/
759/*--- Sanity checking the data structures                      ---*/
760/*----------------------------------------------------------------*/
761
762static UWord stats__sanity_checks = 0;
763
764static void laog__sanity_check ( const HChar* who ); /* fwds */
765
766/* REQUIRED INVARIANTS:
767
768   Thread vs Segment/Lock/SecMaps
769
770      for each t in Threads {
771
772         // Thread.lockset: each element is really a valid Lock
773
774         // Thread.lockset: each Lock in set is actually held by that thread
775         for lk in Thread.lockset
776            lk == LockedBy(t)
777
778         // Thread.csegid is a valid SegmentID
779         // and the associated Segment has .thr == t
780
781      }
782
783      all thread Locksets are pairwise empty under intersection
784      (that is, no lock is claimed to be held by more than one thread)
785      -- this is guaranteed if all locks in locksets point back to their
786      owner threads
787
788   Lock vs Thread/Segment/SecMaps
789
790      for each entry (gla, la) in map_locks
791         gla == la->guest_addr
792
793      for each lk in Locks {
794
795         lk->tag is valid
796         lk->guest_addr does not have shadow state NoAccess
797         if lk == LockedBy(t), then t->lockset contains lk
798         if lk == UnlockedBy(segid) then segid is valid SegmentID
799             and can be mapped to a valid Segment(seg)
800             and seg->thr->lockset does not contain lk
801         if lk == UnlockedNew then (no lockset contains lk)
802
803         secmaps for lk has .mbHasLocks == True
804
805      }
806
807   Segment vs Thread/Lock/SecMaps
808
809      the Segment graph is a dag (no cycles)
810      all of the Segment graph must be reachable from the segids
811         mentioned in the Threads
812
813      for seg in Segments {
814
815         seg->thr is a sane Thread
816
817      }
818
819   SecMaps vs Segment/Thread/Lock
820
821      for sm in SecMaps {
822
823         sm properly aligned
824         if any shadow word is ShR or ShM then .mbHasShared == True
825
826         for each Excl(segid) state
827            map_segments_lookup maps to a sane Segment(seg)
828         for each ShM/ShR(tsetid,lsetid) state
829            each lk in lset is a valid Lock
830            each thr in tset is a valid thread, which is non-dead
831
832      }
833*/
834
835
836/* Return True iff 'thr' holds 'lk' in some mode. */
837static Bool thread_is_a_holder_of_Lock ( Thread* thr, Lock* lk )
838{
839   if (lk->heldBy)
840      return VG_(elemBag)( lk->heldBy, (UWord)thr ) > 0;
841   else
842      return False;
843}
844
845/* Sanity check Threads, as far as possible */
846__attribute__((noinline))
847static void threads__sanity_check ( const HChar* who )
848{
849#define BAD(_str) do { how = (_str); goto bad; } while (0)
850   const HChar* how = "no error";
851   Thread*   thr;
852   WordSetID wsA, wsW;
853   UWord*    ls_words;
854   UWord     ls_size, i;
855   Lock*     lk;
856   for (thr = admin_threads; thr; thr = thr->admin) {
857      if (!HG_(is_sane_Thread)(thr)) BAD("1");
858      wsA = thr->locksetA;
859      wsW = thr->locksetW;
860      // locks held in W mode are a subset of all locks held
861      if (!HG_(isSubsetOf)( univ_lsets, wsW, wsA )) BAD("7");
862      HG_(getPayloadWS)( &ls_words, &ls_size, univ_lsets, wsA );
863      for (i = 0; i < ls_size; i++) {
864         lk = (Lock*)ls_words[i];
865         // Thread.lockset: each element is really a valid Lock
866         if (!HG_(is_sane_LockN)(lk)) BAD("2");
867         // Thread.lockset: each Lock in set is actually held by that
868         // thread
869         if (!thread_is_a_holder_of_Lock(thr,lk)) BAD("3");
870      }
871   }
872   return;
873  bad:
874   VG_(printf)("threads__sanity_check: who=\"%s\", bad=\"%s\"\n", who, how);
875   tl_assert(0);
876#undef BAD
877}
878
879
880/* Sanity check Locks, as far as possible */
881__attribute__((noinline))
882static void locks__sanity_check ( const HChar* who )
883{
884#define BAD(_str) do { how = (_str); goto bad; } while (0)
885   const HChar* how = "no error";
886   Addr      gla;
887   Lock*     lk;
888   Int       i;
889   // # entries in admin_locks == # entries in map_locks
890   for (i = 0, lk = admin_locks;  lk;  i++, lk = lk->admin_next)
891      ;
892   if (i != VG_(sizeFM)(map_locks)) BAD("1");
893   // for each entry (gla, lk) in map_locks
894   //      gla == lk->guest_addr
895   VG_(initIterFM)( map_locks );
896   while (VG_(nextIterFM)( map_locks,
897                           (UWord*)&gla, (UWord*)&lk )) {
898      if (lk->guestaddr != gla) BAD("2");
899   }
900   VG_(doneIterFM)( map_locks );
901   // scan through admin_locks ...
902   for (lk = admin_locks; lk; lk = lk->admin_next) {
903      // lock is sane.  Quite comprehensive, also checks that
904      // referenced (holder) threads are sane.
905      if (!HG_(is_sane_LockN)(lk)) BAD("3");
906      // map_locks binds guest address back to this lock
907      if (lk != map_locks_maybe_lookup(lk->guestaddr)) BAD("4");
908      // look at all threads mentioned as holders of this lock.  Ensure
909      // this lock is mentioned in their locksets.
910      if (lk->heldBy) {
911         Thread* thr;
912         UWord   count;
913         VG_(initIterBag)( lk->heldBy );
914         while (VG_(nextIterBag)( lk->heldBy,
915                                  (UWord*)&thr, &count )) {
916            // HG_(is_sane_LockN) above ensures these
917            tl_assert(count >= 1);
918            tl_assert(HG_(is_sane_Thread)(thr));
919            if (!HG_(elemWS)(univ_lsets, thr->locksetA, (UWord)lk))
920               BAD("6");
921            // also check the w-only lockset
922            if (lk->heldW
923                && !HG_(elemWS)(univ_lsets, thr->locksetW, (UWord)lk))
924               BAD("7");
925            if ((!lk->heldW)
926                && HG_(elemWS)(univ_lsets, thr->locksetW, (UWord)lk))
927               BAD("8");
928         }
929         VG_(doneIterBag)( lk->heldBy );
930      } else {
931         /* lock not held by anybody */
932         if (lk->heldW) BAD("9"); /* should be False if !heldBy */
933         // since lk is unheld, then (no lockset contains lk)
934         // hmm, this is really too expensive to check.  Hmm.
935      }
936   }
937
938   return;
939  bad:
940   VG_(printf)("locks__sanity_check: who=\"%s\", bad=\"%s\"\n", who, how);
941   tl_assert(0);
942#undef BAD
943}
944
945
946static void all_except_Locks__sanity_check ( const HChar* who ) {
947   stats__sanity_checks++;
948   if (0) VG_(printf)("all_except_Locks__sanity_check(%s)\n", who);
949   threads__sanity_check(who);
950   if (HG_(clo_track_lockorders))
951      laog__sanity_check(who);
952}
953static void all__sanity_check ( const HChar* who ) {
954   all_except_Locks__sanity_check(who);
955   locks__sanity_check(who);
956}
957
958
959/*----------------------------------------------------------------*/
960/*--- Shadow value and address range handlers                  ---*/
961/*----------------------------------------------------------------*/
962
963static void laog__pre_thread_acquires_lock ( Thread*, Lock* ); /* fwds */
964//static void laog__handle_lock_deletions    ( WordSetID ); /* fwds */
965static inline Thread* get_current_Thread ( void ); /* fwds */
966__attribute__((noinline))
967static void laog__handle_one_lock_deletion ( Lock* lk ); /* fwds */
968
969
970/* Block-copy states (needed for implementing realloc()). */
971/* FIXME this copies shadow memory; it doesn't apply the MSM to it.
972   Is that a problem? (hence 'scopy' rather than 'ccopy') */
973static void shadow_mem_scopy_range ( Thread* thr,
974                                     Addr src, Addr dst, SizeT len )
975{
976   Thr*     hbthr = thr->hbthr;
977   tl_assert(hbthr);
978   libhb_copy_shadow_state( hbthr, src, dst, len );
979}
980
981static void shadow_mem_cread_range ( Thread* thr, Addr a, SizeT len )
982{
983   Thr*     hbthr = thr->hbthr;
984   tl_assert(hbthr);
985   LIBHB_CREAD_N(hbthr, a, len);
986}
987
988static void shadow_mem_cwrite_range ( Thread* thr, Addr a, SizeT len ) {
989   Thr*     hbthr = thr->hbthr;
990   tl_assert(hbthr);
991   LIBHB_CWRITE_N(hbthr, a, len);
992}
993
994static void shadow_mem_make_New ( Thread* thr, Addr a, SizeT len )
995{
996   libhb_srange_new( thr->hbthr, a, len );
997}
998
999static void shadow_mem_make_NoAccess_NoFX ( Thread* thr, Addr aIN, SizeT len )
1000{
1001   if (0 && len > 500)
1002      VG_(printf)("make NoAccess_NoFX ( %#lx, %ld )\n", aIN, len );
1003   // has no effect (NoFX)
1004   libhb_srange_noaccess_NoFX( thr->hbthr, aIN, len );
1005}
1006
1007static void shadow_mem_make_NoAccess_AHAE ( Thread* thr, Addr aIN, SizeT len )
1008{
1009   if (0 && len > 500)
1010      VG_(printf)("make NoAccess_AHAE ( %#lx, %ld )\n", aIN, len );
1011   // Actually Has An Effect (AHAE)
1012   libhb_srange_noaccess_AHAE( thr->hbthr, aIN, len );
1013}
1014
1015static void shadow_mem_make_Untracked ( Thread* thr, Addr aIN, SizeT len )
1016{
1017   if (0 && len > 500)
1018      VG_(printf)("make Untracked ( %#lx, %ld )\n", aIN, len );
1019   libhb_srange_untrack( thr->hbthr, aIN, len );
1020}
1021
1022
1023/*----------------------------------------------------------------*/
1024/*--- Event handlers (evh__* functions)                        ---*/
1025/*--- plus helpers (evhH__* functions)                         ---*/
1026/*----------------------------------------------------------------*/
1027
1028/*--------- Event handler helpers (evhH__* functions) ---------*/
1029
1030/* Create a new segment for 'thr', making it depend (.prev) on its
1031   existing segment, bind together the SegmentID and Segment, and
1032   return both of them.  Also update 'thr' so it references the new
1033   Segment. */
1034//zz static
1035//zz void evhH__start_new_segment_for_thread ( /*OUT*/SegmentID* new_segidP,
1036//zz                                           /*OUT*/Segment** new_segP,
1037//zz                                           Thread* thr )
1038//zz {
1039//zz    Segment* cur_seg;
1040//zz    tl_assert(new_segP);
1041//zz    tl_assert(new_segidP);
1042//zz    tl_assert(HG_(is_sane_Thread)(thr));
1043//zz    cur_seg = map_segments_lookup( thr->csegid );
1044//zz    tl_assert(cur_seg);
1045//zz    tl_assert(cur_seg->thr == thr); /* all sane segs should point back
1046//zz                                       at their owner thread. */
1047//zz    *new_segP = mk_Segment( thr, cur_seg, NULL/*other*/ );
1048//zz    *new_segidP = alloc_SegmentID();
1049//zz    map_segments_add( *new_segidP, *new_segP );
1050//zz    thr->csegid = *new_segidP;
1051//zz }
1052
1053
1054/* The lock at 'lock_ga' has acquired a writer.  Make all necessary
1055   updates, and also do all possible error checks. */
1056static
1057void evhH__post_thread_w_acquires_lock ( Thread* thr,
1058                                         LockKind lkk, Addr lock_ga )
1059{
1060   Lock* lk;
1061
1062   /* Basically what we need to do is call lockN_acquire_writer.
1063      However, that will barf if any 'invalid' lock states would
1064      result.  Therefore check before calling.  Side effect is that
1065      'HG_(is_sane_LockN)(lk)' is both a pre- and post-condition of this
1066      routine.
1067
1068      Because this routine is only called after successful lock
1069      acquisition, we should not be asked to move the lock into any
1070      invalid states.  Requests to do so are bugs in libpthread, since
1071      that should have rejected any such requests. */
1072
1073   tl_assert(HG_(is_sane_Thread)(thr));
1074   /* Try to find the lock.  If we can't, then create a new one with
1075      kind 'lkk'. */
1076   lk = map_locks_lookup_or_create(
1077           lkk, lock_ga, map_threads_reverse_lookup_SLOW(thr) );
1078   tl_assert( HG_(is_sane_LockN)(lk) );
1079
1080   /* check libhb level entities exist */
1081   tl_assert(thr->hbthr);
1082   tl_assert(lk->hbso);
1083
1084   if (lk->heldBy == NULL) {
1085      /* the lock isn't held.  Simple. */
1086      tl_assert(!lk->heldW);
1087      lockN_acquire_writer( lk, thr );
1088      /* acquire a dependency from the lock's VCs */
1089      libhb_so_recv( thr->hbthr, lk->hbso, True/*strong_recv*/ );
1090      goto noerror;
1091   }
1092
1093   /* So the lock is already held.  If held as a r-lock then
1094      libpthread must be buggy. */
1095   tl_assert(lk->heldBy);
1096   if (!lk->heldW) {
1097      HG_(record_error_Misc)(
1098         thr, "Bug in libpthread: write lock "
1099              "granted on rwlock which is currently rd-held");
1100      goto error;
1101   }
1102
1103   /* So the lock is held in w-mode.  If it's held by some other
1104      thread, then libpthread must be buggy. */
1105   tl_assert(VG_(sizeUniqueBag)(lk->heldBy) == 1); /* from precondition */
1106
1107   if (thr != (Thread*)VG_(anyElementOfBag)(lk->heldBy)) {
1108      HG_(record_error_Misc)(
1109         thr, "Bug in libpthread: write lock "
1110              "granted on mutex/rwlock which is currently "
1111              "wr-held by a different thread");
1112      goto error;
1113   }
1114
1115   /* So the lock is already held in w-mode by 'thr'.  That means this
1116      is an attempt to lock it recursively, which is only allowable
1117      for LK_mbRec kinded locks.  Since this routine is called only
1118      once the lock has been acquired, this must also be a libpthread
1119      bug. */
1120   if (lk->kind != LK_mbRec) {
1121      HG_(record_error_Misc)(
1122         thr, "Bug in libpthread: recursive write lock "
1123              "granted on mutex/wrlock which does not "
1124              "support recursion");
1125      goto error;
1126   }
1127
1128   /* So we are recursively re-locking a lock we already w-hold. */
1129   lockN_acquire_writer( lk, thr );
1130   /* acquire a dependency from the lock's VC.  Probably pointless,
1131      but also harmless. */
1132   libhb_so_recv( thr->hbthr, lk->hbso, True/*strong_recv*/ );
1133   goto noerror;
1134
1135  noerror:
1136   if (HG_(clo_track_lockorders)) {
1137      /* check lock order acquisition graph, and update.  This has to
1138         happen before the lock is added to the thread's locksetA/W. */
1139      laog__pre_thread_acquires_lock( thr, lk );
1140   }
1141   /* update the thread's held-locks set */
1142   thr->locksetA = HG_(addToWS)( univ_lsets, thr->locksetA, (UWord)lk );
1143   thr->locksetW = HG_(addToWS)( univ_lsets, thr->locksetW, (UWord)lk );
1144   /* fall through */
1145
1146  error:
1147   tl_assert(HG_(is_sane_LockN)(lk));
1148}
1149
1150
1151/* The lock at 'lock_ga' has acquired a reader.  Make all necessary
1152   updates, and also do all possible error checks. */
1153static
1154void evhH__post_thread_r_acquires_lock ( Thread* thr,
1155                                         LockKind lkk, Addr lock_ga )
1156{
1157   Lock* lk;
1158
1159   /* Basically what we need to do is call lockN_acquire_reader.
1160      However, that will barf if any 'invalid' lock states would
1161      result.  Therefore check before calling.  Side effect is that
1162      'HG_(is_sane_LockN)(lk)' is both a pre- and post-condition of this
1163      routine.
1164
1165      Because this routine is only called after successful lock
1166      acquisition, we should not be asked to move the lock into any
1167      invalid states.  Requests to do so are bugs in libpthread, since
1168      that should have rejected any such requests. */
1169
1170   tl_assert(HG_(is_sane_Thread)(thr));
1171   /* Try to find the lock.  If we can't, then create a new one with
1172      kind 'lkk'.  Only a reader-writer lock can be read-locked,
1173      hence the first assertion. */
1174   tl_assert(lkk == LK_rdwr);
1175   lk = map_locks_lookup_or_create(
1176           lkk, lock_ga, map_threads_reverse_lookup_SLOW(thr) );
1177   tl_assert( HG_(is_sane_LockN)(lk) );
1178
1179   /* check libhb level entities exist */
1180   tl_assert(thr->hbthr);
1181   tl_assert(lk->hbso);
1182
1183   if (lk->heldBy == NULL) {
1184      /* the lock isn't held.  Simple. */
1185      tl_assert(!lk->heldW);
1186      lockN_acquire_reader( lk, thr );
1187      /* acquire a dependency from the lock's VC */
1188      libhb_so_recv( thr->hbthr, lk->hbso, False/*!strong_recv*/ );
1189      goto noerror;
1190   }
1191
1192   /* So the lock is already held.  If held as a w-lock then
1193      libpthread must be buggy. */
1194   tl_assert(lk->heldBy);
1195   if (lk->heldW) {
1196      HG_(record_error_Misc)( thr, "Bug in libpthread: read lock "
1197                                   "granted on rwlock which is "
1198                                   "currently wr-held");
1199      goto error;
1200   }
1201
1202   /* Easy enough.  In short anybody can get a read-lock on a rwlock
1203      provided it is either unlocked or already in rd-held. */
1204   lockN_acquire_reader( lk, thr );
1205   /* acquire a dependency from the lock's VC.  Probably pointless,
1206      but also harmless. */
1207   libhb_so_recv( thr->hbthr, lk->hbso, False/*!strong_recv*/ );
1208   goto noerror;
1209
1210  noerror:
1211   if (HG_(clo_track_lockorders)) {
1212      /* check lock order acquisition graph, and update.  This has to
1213         happen before the lock is added to the thread's locksetA/W. */
1214      laog__pre_thread_acquires_lock( thr, lk );
1215   }
1216   /* update the thread's held-locks set */
1217   thr->locksetA = HG_(addToWS)( univ_lsets, thr->locksetA, (UWord)lk );
1218   /* but don't update thr->locksetW, since lk is only rd-held */
1219   /* fall through */
1220
1221  error:
1222   tl_assert(HG_(is_sane_LockN)(lk));
1223}
1224
1225
1226/* The lock at 'lock_ga' is just about to be unlocked.  Make all
1227   necessary updates, and also do all possible error checks. */
1228static
1229void evhH__pre_thread_releases_lock ( Thread* thr,
1230                                      Addr lock_ga, Bool isRDWR )
1231{
1232   Lock* lock;
1233   Word  n;
1234   Bool  was_heldW;
1235
1236   /* This routine is called prior to a lock release, before
1237      libpthread has had a chance to validate the call.  Hence we need
1238      to detect and reject any attempts to move the lock into an
1239      invalid state.  Such attempts are bugs in the client.
1240
1241      isRDWR is True if we know from the wrapper context that lock_ga
1242      should refer to a reader-writer lock, and is False if [ditto]
1243      lock_ga should refer to a standard mutex. */
1244
1245   tl_assert(HG_(is_sane_Thread)(thr));
1246   lock = map_locks_maybe_lookup( lock_ga );
1247
1248   if (!lock) {
1249      /* We know nothing about a lock at 'lock_ga'.  Nevertheless
1250         the client is trying to unlock it.  So complain, then ignore
1251         the attempt. */
1252      HG_(record_error_UnlockBogus)( thr, lock_ga );
1253      return;
1254   }
1255
1256   tl_assert(lock->guestaddr == lock_ga);
1257   tl_assert(HG_(is_sane_LockN)(lock));
1258
1259   if (isRDWR && lock->kind != LK_rdwr) {
1260      HG_(record_error_Misc)( thr, "pthread_rwlock_unlock with a "
1261                                   "pthread_mutex_t* argument " );
1262   }
1263   if ((!isRDWR) && lock->kind == LK_rdwr) {
1264      HG_(record_error_Misc)( thr, "pthread_mutex_unlock with a "
1265                                   "pthread_rwlock_t* argument " );
1266   }
1267
1268   if (!lock->heldBy) {
1269      /* The lock is not held.  This indicates a serious bug in the
1270         client. */
1271      tl_assert(!lock->heldW);
1272      HG_(record_error_UnlockUnlocked)( thr, lock );
1273      tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetA, (UWord)lock ));
1274      tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetW, (UWord)lock ));
1275      goto error;
1276   }
1277
1278   /* test just above dominates */
1279   tl_assert(lock->heldBy);
1280   was_heldW = lock->heldW;
1281
1282   /* The lock is held.  Is this thread one of the holders?  If not,
1283      report a bug in the client. */
1284   n = VG_(elemBag)( lock->heldBy, (UWord)thr );
1285   tl_assert(n >= 0);
1286   if (n == 0) {
1287      /* We are not a current holder of the lock.  This is a bug in
1288         the guest, and (per POSIX pthread rules) the unlock
1289         attempt will fail.  So just complain and do nothing
1290         else. */
1291      Thread* realOwner = (Thread*)VG_(anyElementOfBag)( lock->heldBy );
1292      tl_assert(HG_(is_sane_Thread)(realOwner));
1293      tl_assert(realOwner != thr);
1294      tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetA, (UWord)lock ));
1295      tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetW, (UWord)lock ));
1296      HG_(record_error_UnlockForeign)( thr, realOwner, lock );
1297      goto error;
1298   }
1299
1300   /* Ok, we hold the lock 'n' times. */
1301   tl_assert(n >= 1);
1302
1303   lockN_release( lock, thr );
1304
1305   n--;
1306   tl_assert(n >= 0);
1307
1308   if (n > 0) {
1309      tl_assert(lock->heldBy);
1310      tl_assert(n == VG_(elemBag)( lock->heldBy, (UWord)thr ));
1311      /* We still hold the lock.  So either it's a recursive lock
1312         or a rwlock which is currently r-held. */
1313      tl_assert(lock->kind == LK_mbRec
1314                || (lock->kind == LK_rdwr && !lock->heldW));
1315      tl_assert(HG_(elemWS)( univ_lsets, thr->locksetA, (UWord)lock ));
1316      if (lock->heldW)
1317         tl_assert(HG_(elemWS)( univ_lsets, thr->locksetW, (UWord)lock ));
1318      else
1319         tl_assert(!HG_(elemWS)( univ_lsets, thr->locksetW, (UWord)lock ));
1320   } else {
1321      /* n is zero.  This means we don't hold the lock any more.  But
1322         if it's a rwlock held in r-mode, someone else could still
1323         hold it.  Just do whatever sanity checks we can. */
1324      if (lock->kind == LK_rdwr && lock->heldBy) {
1325         /* It's a rwlock.  We no longer hold it but we used to;
1326            nevertheless it still appears to be held by someone else.
1327            The implication is that, prior to this release, it must
1328            have been shared by us and and whoever else is holding it;
1329            which in turn implies it must be r-held, since a lock
1330            can't be w-held by more than one thread. */
1331         /* The lock is now R-held by somebody else: */
1332         tl_assert(lock->heldW == False);
1333      } else {
1334         /* Normal case.  It's either not a rwlock, or it's a rwlock
1335            that we used to hold in w-mode (which is pretty much the
1336            same thing as a non-rwlock.)  Since this transaction is
1337            atomic (V does not allow multiple threads to run
1338            simultaneously), it must mean the lock is now not held by
1339            anybody.  Hence assert for it. */
1340         /* The lock is now not held by anybody: */
1341         tl_assert(!lock->heldBy);
1342         tl_assert(lock->heldW == False);
1343      }
1344      //if (lock->heldBy) {
1345      //   tl_assert(0 == VG_(elemBag)( lock->heldBy, (UWord)thr ));
1346      //}
1347      /* update this thread's lockset accordingly. */
1348      thr->locksetA
1349         = HG_(delFromWS)( univ_lsets, thr->locksetA, (UWord)lock );
1350      thr->locksetW
1351         = HG_(delFromWS)( univ_lsets, thr->locksetW, (UWord)lock );
1352      /* push our VC into the lock */
1353      tl_assert(thr->hbthr);
1354      tl_assert(lock->hbso);
1355      /* If the lock was previously W-held, then we want to do a
1356         strong send, and if previously R-held, then a weak send. */
1357      libhb_so_send( thr->hbthr, lock->hbso, was_heldW );
1358   }
1359   /* fall through */
1360
1361  error:
1362   tl_assert(HG_(is_sane_LockN)(lock));
1363}
1364
1365
1366/* ---------------------------------------------------------- */
1367/* -------- Event handlers proper (evh__* functions) -------- */
1368/* ---------------------------------------------------------- */
1369
1370/* What is the Thread* for the currently running thread?  This is
1371   absolutely performance critical.  We receive notifications from the
1372   core for client code starts/stops, and cache the looked-up result
1373   in 'current_Thread'.  Hence, for the vast majority of requests,
1374   finding the current thread reduces to a read of a global variable,
1375   provided get_current_Thread_in_C_C is inlined.
1376
1377   Outside of client code, current_Thread is NULL, and presumably
1378   any uses of it will cause a segfault.  Hence:
1379
1380   - for uses definitely within client code, use
1381     get_current_Thread_in_C_C.
1382
1383   - for all other uses, use get_current_Thread.
1384*/
1385
1386static Thread *current_Thread      = NULL,
1387              *current_Thread_prev = NULL;
1388
1389static void evh__start_client_code ( ThreadId tid, ULong nDisp ) {
1390   if (0) VG_(printf)("start %d %llu\n", (Int)tid, nDisp);
1391   tl_assert(current_Thread == NULL);
1392   current_Thread = map_threads_lookup( tid );
1393   tl_assert(current_Thread != NULL);
1394   if (current_Thread != current_Thread_prev) {
1395      libhb_Thr_resumes( current_Thread->hbthr );
1396      current_Thread_prev = current_Thread;
1397   }
1398}
1399static void evh__stop_client_code ( ThreadId tid, ULong nDisp ) {
1400   if (0) VG_(printf)(" stop %d %llu\n", (Int)tid, nDisp);
1401   tl_assert(current_Thread != NULL);
1402   current_Thread = NULL;
1403   libhb_maybe_GC();
1404}
1405static inline Thread* get_current_Thread_in_C_C ( void ) {
1406   return current_Thread;
1407}
1408static inline Thread* get_current_Thread ( void ) {
1409   ThreadId coretid;
1410   Thread*  thr;
1411   thr = get_current_Thread_in_C_C();
1412   if (LIKELY(thr))
1413      return thr;
1414   /* evidently not in client code.  Do it the slow way. */
1415   coretid = VG_(get_running_tid)();
1416   /* FIXME: get rid of the following kludge.  It exists because
1417      evh__new_mem is called during initialisation (as notification
1418      of initial memory layout) and VG_(get_running_tid)() returns
1419      VG_INVALID_THREADID at that point. */
1420   if (coretid == VG_INVALID_THREADID)
1421      coretid = 1; /* KLUDGE */
1422   thr = map_threads_lookup( coretid );
1423   return thr;
1424}
1425
1426static
1427void evh__new_mem ( Addr a, SizeT len ) {
1428   if (SHOW_EVENTS >= 2)
1429      VG_(printf)("evh__new_mem(%p, %lu)\n", (void*)a, len );
1430   shadow_mem_make_New( get_current_Thread(), a, len );
1431   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1432      all__sanity_check("evh__new_mem-post");
1433}
1434
1435static
1436void evh__new_mem_stack ( Addr a, SizeT len ) {
1437   if (SHOW_EVENTS >= 2)
1438      VG_(printf)("evh__new_mem_stack(%p, %lu)\n", (void*)a, len );
1439   shadow_mem_make_New( get_current_Thread(),
1440                        -VG_STACK_REDZONE_SZB + a, len );
1441   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1442      all__sanity_check("evh__new_mem_stack-post");
1443}
1444
1445static
1446void evh__new_mem_w_tid ( Addr a, SizeT len, ThreadId tid ) {
1447   if (SHOW_EVENTS >= 2)
1448      VG_(printf)("evh__new_mem_w_tid(%p, %lu)\n", (void*)a, len );
1449   shadow_mem_make_New( get_current_Thread(), a, len );
1450   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1451      all__sanity_check("evh__new_mem_w_tid-post");
1452}
1453
1454static
1455void evh__new_mem_w_perms ( Addr a, SizeT len,
1456                            Bool rr, Bool ww, Bool xx, ULong di_handle ) {
1457   if (SHOW_EVENTS >= 1)
1458      VG_(printf)("evh__new_mem_w_perms(%p, %lu, %d,%d,%d)\n",
1459                  (void*)a, len, (Int)rr, (Int)ww, (Int)xx );
1460   if (rr || ww || xx)
1461      shadow_mem_make_New( get_current_Thread(), a, len );
1462   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1463      all__sanity_check("evh__new_mem_w_perms-post");
1464}
1465
1466static
1467void evh__set_perms ( Addr a, SizeT len,
1468                      Bool rr, Bool ww, Bool xx ) {
1469   // This handles mprotect requests.  If the memory is being put
1470   // into no-R no-W state, paint it as NoAccess, for the reasons
1471   // documented at evh__die_mem_munmap().
1472   if (SHOW_EVENTS >= 1)
1473      VG_(printf)("evh__set_perms(%p, %lu, r=%d w=%d x=%d)\n",
1474                  (void*)a, len, (Int)rr, (Int)ww, (Int)xx );
1475   /* Hmm.  What should we do here, that actually makes any sense?
1476      Let's say: if neither readable nor writable, then declare it
1477      NoAccess, else leave it alone. */
1478   if (!(rr || ww))
1479      shadow_mem_make_NoAccess_AHAE( get_current_Thread(), a, len );
1480   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1481      all__sanity_check("evh__set_perms-post");
1482}
1483
1484static
1485void evh__die_mem ( Addr a, SizeT len ) {
1486   // Urr, libhb ignores this.
1487   if (SHOW_EVENTS >= 2)
1488      VG_(printf)("evh__die_mem(%p, %lu)\n", (void*)a, len );
1489   shadow_mem_make_NoAccess_NoFX( get_current_Thread(), a, len );
1490   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1491      all__sanity_check("evh__die_mem-post");
1492}
1493
1494static
1495void evh__die_mem_munmap ( Addr a, SizeT len ) {
1496   // It's important that libhb doesn't ignore this.  If, as is likely,
1497   // the client is subject to address space layout randomization,
1498   // then unmapped areas may never get remapped over, even in long
1499   // runs.  If we just ignore them we wind up with large resource
1500   // (VTS) leaks in libhb.  So force them to NoAccess, so that all
1501   // VTS references in the affected area are dropped.  Marking memory
1502   // as NoAccess is expensive, but we assume that munmap is sufficiently
1503   // rare that the space gains of doing this are worth the costs.
1504   if (SHOW_EVENTS >= 2)
1505      VG_(printf)("evh__die_mem_munmap(%p, %lu)\n", (void*)a, len );
1506   shadow_mem_make_NoAccess_AHAE( get_current_Thread(), a, len );
1507}
1508
1509static
1510void evh__untrack_mem ( Addr a, SizeT len ) {
1511   // Libhb doesn't ignore this.
1512   if (SHOW_EVENTS >= 2)
1513      VG_(printf)("evh__untrack_mem(%p, %lu)\n", (void*)a, len );
1514   shadow_mem_make_Untracked( get_current_Thread(), a, len );
1515   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1516      all__sanity_check("evh__untrack_mem-post");
1517}
1518
1519static
1520void evh__copy_mem ( Addr src, Addr dst, SizeT len ) {
1521   if (SHOW_EVENTS >= 2)
1522      VG_(printf)("evh__copy_mem(%p, %p, %lu)\n", (void*)src, (void*)dst, len );
1523   shadow_mem_scopy_range( get_current_Thread(), src, dst, len );
1524   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1525      all__sanity_check("evh__copy_mem-post");
1526}
1527
1528static
1529void evh__pre_thread_ll_create ( ThreadId parent, ThreadId child )
1530{
1531   if (SHOW_EVENTS >= 1)
1532      VG_(printf)("evh__pre_thread_ll_create(p=%d, c=%d)\n",
1533                  (Int)parent, (Int)child );
1534
1535   if (parent != VG_INVALID_THREADID) {
1536      Thread* thr_p;
1537      Thread* thr_c;
1538      Thr*    hbthr_p;
1539      Thr*    hbthr_c;
1540
1541      tl_assert(HG_(is_sane_ThreadId)(parent));
1542      tl_assert(HG_(is_sane_ThreadId)(child));
1543      tl_assert(parent != child);
1544
1545      thr_p = map_threads_maybe_lookup( parent );
1546      thr_c = map_threads_maybe_lookup( child );
1547
1548      tl_assert(thr_p != NULL);
1549      tl_assert(thr_c == NULL);
1550
1551      hbthr_p = thr_p->hbthr;
1552      tl_assert(hbthr_p != NULL);
1553      tl_assert( libhb_get_Thr_hgthread(hbthr_p) == thr_p );
1554
1555      hbthr_c = libhb_create ( hbthr_p );
1556
1557      /* Create a new thread record for the child. */
1558      /* a Thread for the new thread ... */
1559      thr_c = mk_Thread( hbthr_c );
1560      tl_assert( libhb_get_Thr_hgthread(hbthr_c) == NULL );
1561      libhb_set_Thr_hgthread(hbthr_c, thr_c);
1562
1563      /* and bind it in the thread-map table */
1564      map_threads[child] = thr_c;
1565      tl_assert(thr_c->coretid == VG_INVALID_THREADID);
1566      thr_c->coretid = child;
1567
1568      /* Record where the parent is so we can later refer to this in
1569         error messages.
1570
1571         On amd64-linux, this entails a nasty glibc-2.5 specific hack.
1572         The stack snapshot is taken immediately after the parent has
1573         returned from its sys_clone call.  Unfortunately there is no
1574         unwind info for the insn following "syscall" - reading the
1575         glibc sources confirms this.  So we ask for a snapshot to be
1576         taken as if RIP was 3 bytes earlier, in a place where there
1577         is unwind info.  Sigh.
1578      */
1579      { Word first_ip_delta = 0;
1580#       if defined(VGP_amd64_linux)
1581        first_ip_delta = -3;
1582#       endif
1583        thr_c->created_at = VG_(record_ExeContext)(parent, first_ip_delta);
1584      }
1585   }
1586
1587   if (HG_(clo_sanity_flags) & SCE_THREADS)
1588      all__sanity_check("evh__pre_thread_create-post");
1589}
1590
1591static
1592void evh__pre_thread_ll_exit ( ThreadId quit_tid )
1593{
1594   Int     nHeld;
1595   Thread* thr_q;
1596   if (SHOW_EVENTS >= 1)
1597      VG_(printf)("evh__pre_thread_ll_exit(thr=%d)\n",
1598                  (Int)quit_tid );
1599
1600   /* quit_tid has disappeared without joining to any other thread.
1601      Therefore there is no synchronisation event associated with its
1602      exit and so we have to pretty much treat it as if it was still
1603      alive but mysteriously making no progress.  That is because, if
1604      we don't know when it really exited, then we can never say there
1605      is a point in time when we're sure the thread really has
1606      finished, and so we need to consider the possibility that it
1607      lingers indefinitely and continues to interact with other
1608      threads. */
1609   /* However, it might have rendezvous'd with a thread that called
1610      pthread_join with this one as arg, prior to this point (that's
1611      how NPTL works).  In which case there has already been a prior
1612      sync event.  So in any case, just let the thread exit.  On NPTL,
1613      all thread exits go through here. */
1614   tl_assert(HG_(is_sane_ThreadId)(quit_tid));
1615   thr_q = map_threads_maybe_lookup( quit_tid );
1616   tl_assert(thr_q != NULL);
1617
1618   /* Complain if this thread holds any locks. */
1619   nHeld = HG_(cardinalityWS)( univ_lsets, thr_q->locksetA );
1620   tl_assert(nHeld >= 0);
1621   if (nHeld > 0) {
1622      HChar buf[80];
1623      VG_(sprintf)(buf, "Exiting thread still holds %d lock%s",
1624                        nHeld, nHeld > 1 ? "s" : "");
1625      HG_(record_error_Misc)( thr_q, buf );
1626   }
1627
1628   /* Not much to do here:
1629      - tell libhb the thread is gone
1630      - clear the map_threads entry, in order that the Valgrind core
1631        can re-use it. */
1632   /* Cleanup actions (next 5 lines) copied in evh__atfork_child; keep
1633      in sync. */
1634   tl_assert(thr_q->hbthr);
1635   libhb_async_exit(thr_q->hbthr);
1636   tl_assert(thr_q->coretid == quit_tid);
1637   thr_q->coretid = VG_INVALID_THREADID;
1638   map_threads_delete( quit_tid );
1639
1640   if (HG_(clo_sanity_flags) & SCE_THREADS)
1641      all__sanity_check("evh__pre_thread_ll_exit-post");
1642}
1643
1644/* This is called immediately after fork, for the child only.  'tid'
1645   is the only surviving thread (as per POSIX rules on fork() in
1646   threaded programs), so we have to clean up map_threads to remove
1647   entries for any other threads. */
1648static
1649void evh__atfork_child ( ThreadId tid )
1650{
1651   UInt    i;
1652   Thread* thr;
1653   /* Slot 0 should never be used. */
1654   thr = map_threads_maybe_lookup( 0/*INVALID*/ );
1655   tl_assert(!thr);
1656   /* Clean up all other slots except 'tid'. */
1657   for (i = 1; i < VG_N_THREADS; i++) {
1658      if (i == tid)
1659         continue;
1660      thr = map_threads_maybe_lookup(i);
1661      if (!thr)
1662         continue;
1663      /* Cleanup actions (next 5 lines) copied from end of
1664         evh__pre_thread_ll_exit; keep in sync. */
1665      tl_assert(thr->hbthr);
1666      libhb_async_exit(thr->hbthr);
1667      tl_assert(thr->coretid == i);
1668      thr->coretid = VG_INVALID_THREADID;
1669      map_threads_delete(i);
1670   }
1671}
1672
1673
1674static
1675void evh__HG_PTHREAD_JOIN_POST ( ThreadId stay_tid, Thread* quit_thr )
1676{
1677   Thread*  thr_s;
1678   Thread*  thr_q;
1679   Thr*     hbthr_s;
1680   Thr*     hbthr_q;
1681   SO*      so;
1682
1683   if (SHOW_EVENTS >= 1)
1684      VG_(printf)("evh__post_thread_join(stayer=%d, quitter=%p)\n",
1685                  (Int)stay_tid, quit_thr );
1686
1687   tl_assert(HG_(is_sane_ThreadId)(stay_tid));
1688
1689   thr_s = map_threads_maybe_lookup( stay_tid );
1690   thr_q = quit_thr;
1691   tl_assert(thr_s != NULL);
1692   tl_assert(thr_q != NULL);
1693   tl_assert(thr_s != thr_q);
1694
1695   hbthr_s = thr_s->hbthr;
1696   hbthr_q = thr_q->hbthr;
1697   tl_assert(hbthr_s != hbthr_q);
1698   tl_assert( libhb_get_Thr_hgthread(hbthr_s) == thr_s );
1699   tl_assert( libhb_get_Thr_hgthread(hbthr_q) == thr_q );
1700
1701   /* Allocate a temporary synchronisation object and use it to send
1702      an imaginary message from the quitter to the stayer, the purpose
1703      being to generate a dependence from the quitter to the
1704      stayer. */
1705   so = libhb_so_alloc();
1706   tl_assert(so);
1707   /* Send last arg of _so_send as False, since the sending thread
1708      doesn't actually exist any more, so we don't want _so_send to
1709      try taking stack snapshots of it. */
1710   libhb_so_send(hbthr_q, so, True/*strong_send*//*?!? wrt comment above*/);
1711   libhb_so_recv(hbthr_s, so, True/*strong_recv*/);
1712   libhb_so_dealloc(so);
1713
1714   /* Tell libhb that the quitter has been reaped.  Note that we might
1715      have to be cleverer about this, to exclude 2nd and subsequent
1716      notifications for the same hbthr_q, in the case where the app is
1717      buggy (calls pthread_join twice or more on the same thread) AND
1718      where libpthread is also buggy and doesn't return ESRCH on
1719      subsequent calls.  (If libpthread isn't thusly buggy, then the
1720      wrapper for pthread_join in hg_intercepts.c will stop us getting
1721      notified here multiple times for the same joinee.)  See also
1722      comments in helgrind/tests/jointwice.c. */
1723   libhb_joinedwith_done(hbthr_q);
1724
1725   /* evh__pre_thread_ll_exit issues an error message if the exiting
1726      thread holds any locks.  No need to check here. */
1727
1728   /* This holds because, at least when using NPTL as the thread
1729      library, we should be notified the low level thread exit before
1730      we hear of any join event on it.  The low level exit
1731      notification feeds through into evh__pre_thread_ll_exit,
1732      which should clear the map_threads entry for it.  Hence we
1733      expect there to be no map_threads entry at this point. */
1734   tl_assert( map_threads_maybe_reverse_lookup_SLOW(thr_q)
1735              == VG_INVALID_THREADID);
1736
1737   if (HG_(clo_sanity_flags) & SCE_THREADS)
1738      all__sanity_check("evh__post_thread_join-post");
1739}
1740
1741static
1742void evh__pre_mem_read ( CorePart part, ThreadId tid, const HChar* s,
1743                         Addr a, SizeT size) {
1744   if (SHOW_EVENTS >= 2
1745       || (SHOW_EVENTS >= 1 && size != 1))
1746      VG_(printf)("evh__pre_mem_read(ctid=%d, \"%s\", %p, %lu)\n",
1747                  (Int)tid, s, (void*)a, size );
1748   shadow_mem_cread_range( map_threads_lookup(tid), a, size);
1749   if (size >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1750      all__sanity_check("evh__pre_mem_read-post");
1751}
1752
1753static
1754void evh__pre_mem_read_asciiz ( CorePart part, ThreadId tid,
1755                                const HChar* s, Addr a ) {
1756   Int len;
1757   if (SHOW_EVENTS >= 1)
1758      VG_(printf)("evh__pre_mem_asciiz(ctid=%d, \"%s\", %p)\n",
1759                  (Int)tid, s, (void*)a );
1760   // Don't segfault if the string starts in an obviously stupid
1761   // place.  Actually we should check the whole string, not just
1762   // the start address, but that's too much trouble.  At least
1763   // checking the first byte is better than nothing.  See #255009.
1764   if (!VG_(am_is_valid_for_client) (a, 1, VKI_PROT_READ))
1765      return;
1766   len = VG_(strlen)( (HChar*) a );
1767   shadow_mem_cread_range( map_threads_lookup(tid), a, len+1 );
1768   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1769      all__sanity_check("evh__pre_mem_read_asciiz-post");
1770}
1771
1772static
1773void evh__pre_mem_write ( CorePart part, ThreadId tid, const HChar* s,
1774                          Addr a, SizeT size ) {
1775   if (SHOW_EVENTS >= 1)
1776      VG_(printf)("evh__pre_mem_write(ctid=%d, \"%s\", %p, %lu)\n",
1777                  (Int)tid, s, (void*)a, size );
1778   shadow_mem_cwrite_range( map_threads_lookup(tid), a, size);
1779   if (size >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1780      all__sanity_check("evh__pre_mem_write-post");
1781}
1782
1783static
1784void evh__new_mem_heap ( Addr a, SizeT len, Bool is_inited ) {
1785   if (SHOW_EVENTS >= 1)
1786      VG_(printf)("evh__new_mem_heap(%p, %lu, inited=%d)\n",
1787                  (void*)a, len, (Int)is_inited );
1788   // FIXME: this is kinda stupid
1789   if (is_inited) {
1790      shadow_mem_make_New(get_current_Thread(), a, len);
1791   } else {
1792      shadow_mem_make_New(get_current_Thread(), a, len);
1793   }
1794   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1795      all__sanity_check("evh__pre_mem_read-post");
1796}
1797
1798static
1799void evh__die_mem_heap ( Addr a, SizeT len ) {
1800   Thread* thr;
1801   if (SHOW_EVENTS >= 1)
1802      VG_(printf)("evh__die_mem_heap(%p, %lu)\n", (void*)a, len );
1803   thr = get_current_Thread();
1804   tl_assert(thr);
1805   if (HG_(clo_free_is_write)) {
1806      /* Treat frees as if the memory was written immediately prior to
1807         the free.  This shakes out more races, specifically, cases
1808         where memory is referenced by one thread, and freed by
1809         another, and there's no observable synchronisation event to
1810         guarantee that the reference happens before the free. */
1811      shadow_mem_cwrite_range(thr, a, len);
1812   }
1813   shadow_mem_make_NoAccess_NoFX( thr, a, len );
1814   if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))
1815      all__sanity_check("evh__pre_mem_read-post");
1816}
1817
1818/* --- Event handlers called from generated code --- */
1819
1820static VG_REGPARM(1)
1821void evh__mem_help_cread_1(Addr a) {
1822   Thread*  thr = get_current_Thread_in_C_C();
1823   Thr*     hbthr = thr->hbthr;
1824   LIBHB_CREAD_1(hbthr, a);
1825}
1826
1827static VG_REGPARM(1)
1828void evh__mem_help_cread_2(Addr a) {
1829   Thread*  thr = get_current_Thread_in_C_C();
1830   Thr*     hbthr = thr->hbthr;
1831   LIBHB_CREAD_2(hbthr, a);
1832}
1833
1834static VG_REGPARM(1)
1835void evh__mem_help_cread_4(Addr a) {
1836   Thread*  thr = get_current_Thread_in_C_C();
1837   Thr*     hbthr = thr->hbthr;
1838   LIBHB_CREAD_4(hbthr, a);
1839}
1840
1841static VG_REGPARM(1)
1842void evh__mem_help_cread_8(Addr a) {
1843   Thread*  thr = get_current_Thread_in_C_C();
1844   Thr*     hbthr = thr->hbthr;
1845   LIBHB_CREAD_8(hbthr, a);
1846}
1847
1848static VG_REGPARM(2)
1849void evh__mem_help_cread_N(Addr a, SizeT size) {
1850   Thread*  thr = get_current_Thread_in_C_C();
1851   Thr*     hbthr = thr->hbthr;
1852   LIBHB_CREAD_N(hbthr, a, size);
1853}
1854
1855static VG_REGPARM(1)
1856void evh__mem_help_cwrite_1(Addr a) {
1857   Thread*  thr = get_current_Thread_in_C_C();
1858   Thr*     hbthr = thr->hbthr;
1859   LIBHB_CWRITE_1(hbthr, a);
1860}
1861
1862static VG_REGPARM(1)
1863void evh__mem_help_cwrite_2(Addr a) {
1864   Thread*  thr = get_current_Thread_in_C_C();
1865   Thr*     hbthr = thr->hbthr;
1866   LIBHB_CWRITE_2(hbthr, a);
1867}
1868
1869static VG_REGPARM(1)
1870void evh__mem_help_cwrite_4(Addr a) {
1871   Thread*  thr = get_current_Thread_in_C_C();
1872   Thr*     hbthr = thr->hbthr;
1873   LIBHB_CWRITE_4(hbthr, a);
1874}
1875
1876static VG_REGPARM(1)
1877void evh__mem_help_cwrite_8(Addr a) {
1878   Thread*  thr = get_current_Thread_in_C_C();
1879   Thr*     hbthr = thr->hbthr;
1880   LIBHB_CWRITE_8(hbthr, a);
1881}
1882
1883static VG_REGPARM(2)
1884void evh__mem_help_cwrite_N(Addr a, SizeT size) {
1885   Thread*  thr = get_current_Thread_in_C_C();
1886   Thr*     hbthr = thr->hbthr;
1887   LIBHB_CWRITE_N(hbthr, a, size);
1888}
1889
1890
1891/* ------------------------------------------------------- */
1892/* -------------- events to do with mutexes -------------- */
1893/* ------------------------------------------------------- */
1894
1895/* EXPOSITION only: by intercepting lock init events we can show the
1896   user where the lock was initialised, rather than only being able to
1897   show where it was first locked.  Intercepting lock initialisations
1898   is not necessary for the basic operation of the race checker. */
1899static
1900void evh__HG_PTHREAD_MUTEX_INIT_POST( ThreadId tid,
1901                                      void* mutex, Word mbRec )
1902{
1903   if (SHOW_EVENTS >= 1)
1904      VG_(printf)("evh__hg_PTHREAD_MUTEX_INIT_POST(ctid=%d, mbRec=%ld, %p)\n",
1905                  (Int)tid, mbRec, (void*)mutex );
1906   tl_assert(mbRec == 0 || mbRec == 1);
1907   map_locks_lookup_or_create( mbRec ? LK_mbRec : LK_nonRec,
1908                               (Addr)mutex, tid );
1909   if (HG_(clo_sanity_flags) & SCE_LOCKS)
1910      all__sanity_check("evh__hg_PTHREAD_MUTEX_INIT_POST");
1911}
1912
1913static
1914void evh__HG_PTHREAD_MUTEX_DESTROY_PRE( ThreadId tid, void* mutex,
1915                                        Bool mutex_is_init )
1916{
1917   Thread* thr;
1918   Lock*   lk;
1919   if (SHOW_EVENTS >= 1)
1920      VG_(printf)("evh__hg_PTHREAD_MUTEX_DESTROY_PRE"
1921                  "(ctid=%d, %p, isInit=%d)\n",
1922                  (Int)tid, (void*)mutex, (Int)mutex_is_init );
1923
1924   thr = map_threads_maybe_lookup( tid );
1925   /* cannot fail - Thread* must already exist */
1926   tl_assert( HG_(is_sane_Thread)(thr) );
1927
1928   lk = map_locks_maybe_lookup( (Addr)mutex );
1929
1930   if (lk == NULL && mutex_is_init) {
1931      /* We're destroying a mutex which we don't have any record of,
1932         and which appears to have the value PTHREAD_MUTEX_INITIALIZER.
1933         Assume it never got used, and so we don't need to do anything
1934         more. */
1935      goto out;
1936   }
1937
1938   if (lk == NULL || (lk->kind != LK_nonRec && lk->kind != LK_mbRec)) {
1939      HG_(record_error_Misc)(
1940         thr, "pthread_mutex_destroy with invalid argument" );
1941   }
1942
1943   if (lk) {
1944      tl_assert( HG_(is_sane_LockN)(lk) );
1945      tl_assert( lk->guestaddr == (Addr)mutex );
1946      if (lk->heldBy) {
1947         /* Basically act like we unlocked the lock */
1948         HG_(record_error_Misc)(
1949            thr, "pthread_mutex_destroy of a locked mutex" );
1950         /* remove lock from locksets of all owning threads */
1951         remove_Lock_from_locksets_of_all_owning_Threads( lk );
1952         VG_(deleteBag)( lk->heldBy );
1953         lk->heldBy = NULL;
1954         lk->heldW = False;
1955         lk->acquired_at = NULL;
1956      }
1957      tl_assert( !lk->heldBy );
1958      tl_assert( HG_(is_sane_LockN)(lk) );
1959
1960      if (HG_(clo_track_lockorders))
1961         laog__handle_one_lock_deletion(lk);
1962      map_locks_delete( lk->guestaddr );
1963      del_LockN( lk );
1964   }
1965
1966  out:
1967   if (HG_(clo_sanity_flags) & SCE_LOCKS)
1968      all__sanity_check("evh__hg_PTHREAD_MUTEX_DESTROY_PRE");
1969}
1970
1971static void evh__HG_PTHREAD_MUTEX_LOCK_PRE ( ThreadId tid,
1972                                             void* mutex, Word isTryLock )
1973{
1974   /* Just check the mutex is sane; nothing else to do. */
1975   // 'mutex' may be invalid - not checked by wrapper
1976   Thread* thr;
1977   Lock*   lk;
1978   if (SHOW_EVENTS >= 1)
1979      VG_(printf)("evh__hg_PTHREAD_MUTEX_LOCK_PRE(ctid=%d, mutex=%p)\n",
1980                  (Int)tid, (void*)mutex );
1981
1982   tl_assert(isTryLock == 0 || isTryLock == 1);
1983   thr = map_threads_maybe_lookup( tid );
1984   tl_assert(thr); /* cannot fail - Thread* must already exist */
1985
1986   lk = map_locks_maybe_lookup( (Addr)mutex );
1987
1988   if (lk && (lk->kind == LK_rdwr)) {
1989      HG_(record_error_Misc)( thr, "pthread_mutex_lock with a "
1990                                   "pthread_rwlock_t* argument " );
1991   }
1992
1993   if ( lk
1994        && isTryLock == 0
1995        && (lk->kind == LK_nonRec || lk->kind == LK_rdwr)
1996        && lk->heldBy
1997        && lk->heldW
1998        && VG_(elemBag)( lk->heldBy, (UWord)thr ) > 0 ) {
1999      /* uh, it's a non-recursive lock and we already w-hold it, and
2000         this is a real lock operation (not a speculative "tryLock"
2001         kind of thing).  Duh.  Deadlock coming up; but at least
2002         produce an error message. */
2003      const HChar* errstr = "Attempt to re-lock a "
2004                            "non-recursive lock I already hold";
2005      const HChar* auxstr = "Lock was previously acquired";
2006      if (lk->acquired_at) {
2007         HG_(record_error_Misc_w_aux)( thr, errstr, auxstr, lk->acquired_at );
2008      } else {
2009         HG_(record_error_Misc)( thr, errstr );
2010      }
2011   }
2012}
2013
2014static void evh__HG_PTHREAD_MUTEX_LOCK_POST ( ThreadId tid, void* mutex )
2015{
2016   // only called if the real library call succeeded - so mutex is sane
2017   Thread* thr;
2018   if (SHOW_EVENTS >= 1)
2019      VG_(printf)("evh__HG_PTHREAD_MUTEX_LOCK_POST(ctid=%d, mutex=%p)\n",
2020                  (Int)tid, (void*)mutex );
2021
2022   thr = map_threads_maybe_lookup( tid );
2023   tl_assert(thr); /* cannot fail - Thread* must already exist */
2024
2025   evhH__post_thread_w_acquires_lock(
2026      thr,
2027      LK_mbRec, /* if not known, create new lock with this LockKind */
2028      (Addr)mutex
2029   );
2030}
2031
2032static void evh__HG_PTHREAD_MUTEX_UNLOCK_PRE ( ThreadId tid, void* mutex )
2033{
2034   // 'mutex' may be invalid - not checked by wrapper
2035   Thread* thr;
2036   if (SHOW_EVENTS >= 1)
2037      VG_(printf)("evh__HG_PTHREAD_MUTEX_UNLOCK_PRE(ctid=%d, mutex=%p)\n",
2038                  (Int)tid, (void*)mutex );
2039
2040   thr = map_threads_maybe_lookup( tid );
2041   tl_assert(thr); /* cannot fail - Thread* must already exist */
2042
2043   evhH__pre_thread_releases_lock( thr, (Addr)mutex, False/*!isRDWR*/ );
2044}
2045
2046static void evh__HG_PTHREAD_MUTEX_UNLOCK_POST ( ThreadId tid, void* mutex )
2047{
2048   // only called if the real library call succeeded - so mutex is sane
2049   Thread* thr;
2050   if (SHOW_EVENTS >= 1)
2051      VG_(printf)("evh__hg_PTHREAD_MUTEX_UNLOCK_POST(ctid=%d, mutex=%p)\n",
2052                  (Int)tid, (void*)mutex );
2053   thr = map_threads_maybe_lookup( tid );
2054   tl_assert(thr); /* cannot fail - Thread* must already exist */
2055
2056   // anything we should do here?
2057}
2058
2059
2060/* ------------------------------------------------------- */
2061/* -------------- events to do with spinlocks ------------ */
2062/* ------------------------------------------------------- */
2063
2064/* All a bit of a kludge.  Pretend we're really dealing with ordinary
2065   pthread_mutex_t's instead, for the most part. */
2066
2067static void evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE( ThreadId tid,
2068                                                     void* slock )
2069{
2070   Thread* thr;
2071   Lock*   lk;
2072   /* In glibc's kludgey world, we're either initialising or unlocking
2073      it.  Since this is the pre-routine, if it is locked, unlock it
2074      and take a dependence edge.  Otherwise, do nothing. */
2075
2076   if (SHOW_EVENTS >= 1)
2077      VG_(printf)("evh__hg_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE"
2078                  "(ctid=%d, slock=%p)\n",
2079                  (Int)tid, (void*)slock );
2080
2081   thr = map_threads_maybe_lookup( tid );
2082   /* cannot fail - Thread* must already exist */;
2083   tl_assert( HG_(is_sane_Thread)(thr) );
2084
2085   lk = map_locks_maybe_lookup( (Addr)slock );
2086   if (lk && lk->heldBy) {
2087      /* it's held.  So do the normal pre-unlock actions, as copied
2088         from evh__HG_PTHREAD_MUTEX_UNLOCK_PRE.  This stupidly
2089         duplicates the map_locks_maybe_lookup. */
2090      evhH__pre_thread_releases_lock( thr, (Addr)slock,
2091                                           False/*!isRDWR*/ );
2092   }
2093}
2094
2095static void evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_POST( ThreadId tid,
2096                                                      void* slock )
2097{
2098   Lock* lk;
2099   /* More kludgery.  If the lock has never been seen before, do
2100      actions as per evh__HG_PTHREAD_MUTEX_INIT_POST.  Else do
2101      nothing. */
2102
2103   if (SHOW_EVENTS >= 1)
2104      VG_(printf)("evh__hg_PTHREAD_SPIN_INIT_OR_UNLOCK_POST"
2105                  "(ctid=%d, slock=%p)\n",
2106                  (Int)tid, (void*)slock );
2107
2108   lk = map_locks_maybe_lookup( (Addr)slock );
2109   if (!lk) {
2110      map_locks_lookup_or_create( LK_nonRec, (Addr)slock, tid );
2111   }
2112}
2113
2114static void evh__HG_PTHREAD_SPIN_LOCK_PRE( ThreadId tid,
2115                                           void* slock, Word isTryLock )
2116{
2117   evh__HG_PTHREAD_MUTEX_LOCK_PRE( tid, slock, isTryLock );
2118}
2119
2120static void evh__HG_PTHREAD_SPIN_LOCK_POST( ThreadId tid,
2121                                            void* slock )
2122{
2123   evh__HG_PTHREAD_MUTEX_LOCK_POST( tid, slock );
2124}
2125
2126static void evh__HG_PTHREAD_SPIN_DESTROY_PRE( ThreadId tid,
2127                                              void* slock )
2128{
2129   evh__HG_PTHREAD_MUTEX_DESTROY_PRE( tid, slock, 0/*!isInit*/ );
2130}
2131
2132
2133/* ----------------------------------------------------- */
2134/* --------------- events to do with CVs --------------- */
2135/* ----------------------------------------------------- */
2136
2137/* A mapping from CV to (the SO associated with it, plus some
2138   auxiliary data for error checking).  When the CV is
2139   signalled/broadcasted upon, we do a 'send' into the SO, and when a
2140   wait on it completes, we do a 'recv' from the SO.  This is believed
2141   to give the correct happens-before events arising from CV
2142   signallings/broadcasts.
2143*/
2144
2145/* .so is the SO for this CV.
2146   .mx_ga is the associated mutex, when .nWaiters > 0
2147
2148   POSIX says effectively that the first pthread_cond_{timed}wait call
2149   causes a dynamic binding between the CV and the mutex, and that
2150   lasts until such time as the waiter count falls to zero.  Hence
2151   need to keep track of the number of waiters in order to do
2152   consistency tracking. */
2153typedef
2154   struct {
2155      SO*   so;       /* libhb-allocated SO */
2156      void* mx_ga;    /* addr of associated mutex, if any */
2157      UWord nWaiters; /* # threads waiting on the CV */
2158   }
2159   CVInfo;
2160
2161
2162/* pthread_cond_t* -> CVInfo* */
2163static WordFM* map_cond_to_CVInfo = NULL;
2164
2165static void map_cond_to_CVInfo_INIT ( void ) {
2166   if (UNLIKELY(map_cond_to_CVInfo == NULL)) {
2167      map_cond_to_CVInfo = VG_(newFM)( HG_(zalloc),
2168                                       "hg.mctCI.1", HG_(free), NULL );
2169      tl_assert(map_cond_to_CVInfo != NULL);
2170   }
2171}
2172
2173static CVInfo* map_cond_to_CVInfo_lookup_or_alloc ( void* cond ) {
2174   UWord key, val;
2175   map_cond_to_CVInfo_INIT();
2176   if (VG_(lookupFM)( map_cond_to_CVInfo, &key, &val, (UWord)cond )) {
2177      tl_assert(key == (UWord)cond);
2178      return (CVInfo*)val;
2179   } else {
2180      SO*     so  = libhb_so_alloc();
2181      CVInfo* cvi = HG_(zalloc)("hg.mctCloa.1", sizeof(CVInfo));
2182      cvi->so     = so;
2183      cvi->mx_ga  = 0;
2184      VG_(addToFM)( map_cond_to_CVInfo, (UWord)cond, (UWord)cvi );
2185      return cvi;
2186   }
2187}
2188
2189static CVInfo* map_cond_to_CVInfo_lookup_NO_alloc ( void* cond ) {
2190   UWord key, val;
2191   map_cond_to_CVInfo_INIT();
2192   if (VG_(lookupFM)( map_cond_to_CVInfo, &key, &val, (UWord)cond )) {
2193      tl_assert(key == (UWord)cond);
2194      return (CVInfo*)val;
2195   } else {
2196      return NULL;
2197   }
2198}
2199
2200static void map_cond_to_CVInfo_delete ( ThreadId tid,
2201                                        void* cond, Bool cond_is_init ) {
2202   Thread*   thr;
2203   UWord keyW, valW;
2204
2205   thr = map_threads_maybe_lookup( tid );
2206   tl_assert(thr); /* cannot fail - Thread* must already exist */
2207
2208   map_cond_to_CVInfo_INIT();
2209   if (VG_(lookupFM)( map_cond_to_CVInfo, &keyW, &valW, (UWord)cond )) {
2210      CVInfo* cvi = (CVInfo*)valW;
2211      tl_assert(keyW == (UWord)cond);
2212      tl_assert(cvi);
2213      tl_assert(cvi->so);
2214      if (cvi->nWaiters > 0) {
2215         HG_(record_error_Misc)(
2216            thr, "pthread_cond_destroy:"
2217                 " destruction of condition variable being waited upon");
2218         /* Destroying a cond var being waited upon outcome is EBUSY and
2219            variable is not destroyed. */
2220         return;
2221      }
2222      if (!VG_(delFromFM)( map_cond_to_CVInfo, &keyW, &valW, (UWord)cond ))
2223         tl_assert(0); // cond var found above, and not here ???
2224      libhb_so_dealloc(cvi->so);
2225      cvi->mx_ga = 0;
2226      HG_(free)(cvi);
2227   } else {
2228      /* We have no record of this CV.  So complain about it
2229         .. except, don't bother to complain if it has exactly the
2230         value PTHREAD_COND_INITIALIZER, since it might be that the CV
2231         was initialised like that but never used. */
2232      if (!cond_is_init) {
2233         HG_(record_error_Misc)(
2234            thr, "pthread_cond_destroy: destruction of unknown cond var");
2235      }
2236   }
2237}
2238
2239static void evh__HG_PTHREAD_COND_SIGNAL_PRE ( ThreadId tid, void* cond )
2240{
2241   /* 'tid' has signalled on 'cond'.  As per the comment above, bind
2242      cond to a SO if it is not already so bound, and 'send' on the
2243      SO.  This is later used by other thread(s) which successfully
2244      exit from a pthread_cond_wait on the same cv; then they 'recv'
2245      from the SO, thereby acquiring a dependency on this signalling
2246      event. */
2247   Thread*   thr;
2248   CVInfo*   cvi;
2249   //Lock*     lk;
2250
2251   if (SHOW_EVENTS >= 1)
2252      VG_(printf)("evh__HG_PTHREAD_COND_SIGNAL_PRE(ctid=%d, cond=%p)\n",
2253                  (Int)tid, (void*)cond );
2254
2255   thr = map_threads_maybe_lookup( tid );
2256   tl_assert(thr); /* cannot fail - Thread* must already exist */
2257
2258   cvi = map_cond_to_CVInfo_lookup_or_alloc( cond );
2259   tl_assert(cvi);
2260   tl_assert(cvi->so);
2261
2262   // error-if: mutex is bogus
2263   // error-if: mutex is not locked
2264   // Hmm.  POSIX doesn't actually say that it's an error to call
2265   // pthread_cond_signal with the associated mutex being unlocked.
2266   // Although it does say that it should be "if consistent scheduling
2267   // is desired."  For that reason, print "dubious" if the lock isn't
2268   // held by any thread.  Skip the "dubious" if it is held by some
2269   // other thread; that sounds straight-out wrong.
2270   //
2271   // Anybody who writes code that signals on a CV without holding
2272   // the associated MX needs to be shipped off to a lunatic asylum
2273   // ASAP, even though POSIX doesn't actually declare such behaviour
2274   // illegal -- it makes code extremely difficult to understand/
2275   // reason about.  In particular it puts the signalling thread in
2276   // a situation where it is racing against the released waiter
2277   // as soon as the signalling is done, and so there needs to be
2278   // some auxiliary synchronisation mechanism in the program that
2279   // makes this safe -- or the race(s) need to be harmless, or
2280   // probably nonexistent.
2281   //
2282   if (1) {
2283      Lock* lk = NULL;
2284      if (cvi->mx_ga != 0) {
2285         lk = map_locks_maybe_lookup( (Addr)cvi->mx_ga );
2286      }
2287      /* note: lk could be NULL.  Be careful. */
2288      if (lk) {
2289         if (lk->kind == LK_rdwr) {
2290            HG_(record_error_Misc)(thr,
2291               "pthread_cond_{signal,broadcast}: associated lock is a rwlock");
2292         }
2293         if (lk->heldBy == NULL) {
2294            HG_(record_error_Misc)(thr,
2295               "pthread_cond_{signal,broadcast}: dubious: "
2296               "associated lock is not held by any thread");
2297         }
2298         if (lk->heldBy != NULL && 0 == VG_(elemBag)(lk->heldBy, (UWord)thr)) {
2299            HG_(record_error_Misc)(thr,
2300               "pthread_cond_{signal,broadcast}: "
2301               "associated lock is not held by calling thread");
2302         }
2303      } else {
2304         /* Couldn't even find the damn thing. */
2305         // But actually .. that's not necessarily an error.  We don't
2306         // know the (CV,MX) binding until a pthread_cond_wait or bcast
2307         // shows us what it is, and if that may not have happened yet.
2308         // So just keep quiet in this circumstance.
2309         //HG_(record_error_Misc)( thr,
2310         //   "pthread_cond_{signal,broadcast}: "
2311         //   "no or invalid mutex associated with cond");
2312      }
2313   }
2314
2315   libhb_so_send( thr->hbthr, cvi->so, True/*strong_send*/ );
2316}
2317
2318/* returns True if it reckons 'mutex' is valid and held by this
2319   thread, else False */
2320static Bool evh__HG_PTHREAD_COND_WAIT_PRE ( ThreadId tid,
2321                                            void* cond, void* mutex )
2322{
2323   Thread* thr;
2324   Lock*   lk;
2325   Bool    lk_valid = True;
2326   CVInfo* cvi;
2327
2328   if (SHOW_EVENTS >= 1)
2329      VG_(printf)("evh__hg_PTHREAD_COND_WAIT_PRE"
2330                  "(ctid=%d, cond=%p, mutex=%p)\n",
2331                  (Int)tid, (void*)cond, (void*)mutex );
2332
2333   thr = map_threads_maybe_lookup( tid );
2334   tl_assert(thr); /* cannot fail - Thread* must already exist */
2335
2336   lk = map_locks_maybe_lookup( (Addr)mutex );
2337
2338   /* Check for stupid mutex arguments.  There are various ways to be
2339      a bozo.  Only complain once, though, even if more than one thing
2340      is wrong. */
2341   if (lk == NULL) {
2342      lk_valid = False;
2343      HG_(record_error_Misc)(
2344         thr,
2345         "pthread_cond_{timed}wait called with invalid mutex" );
2346   } else {
2347      tl_assert( HG_(is_sane_LockN)(lk) );
2348      if (lk->kind == LK_rdwr) {
2349         lk_valid = False;
2350         HG_(record_error_Misc)(
2351            thr, "pthread_cond_{timed}wait called with mutex "
2352                 "of type pthread_rwlock_t*" );
2353      } else
2354         if (lk->heldBy == NULL) {
2355         lk_valid = False;
2356         HG_(record_error_Misc)(
2357            thr, "pthread_cond_{timed}wait called with un-held mutex");
2358      } else
2359      if (lk->heldBy != NULL
2360          && VG_(elemBag)( lk->heldBy, (UWord)thr ) == 0) {
2361         lk_valid = False;
2362         HG_(record_error_Misc)(
2363            thr, "pthread_cond_{timed}wait called with mutex "
2364                 "held by a different thread" );
2365      }
2366   }
2367
2368   // error-if: cond is also associated with a different mutex
2369   cvi = map_cond_to_CVInfo_lookup_or_alloc(cond);
2370   tl_assert(cvi);
2371   tl_assert(cvi->so);
2372   if (cvi->nWaiters == 0) {
2373      /* form initial (CV,MX) binding */
2374      cvi->mx_ga = mutex;
2375   }
2376   else /* check existing (CV,MX) binding */
2377   if (cvi->mx_ga != mutex) {
2378      HG_(record_error_Misc)(
2379         thr, "pthread_cond_{timed}wait: cond is associated "
2380              "with a different mutex");
2381   }
2382   cvi->nWaiters++;
2383
2384   return lk_valid;
2385}
2386
2387static void evh__HG_PTHREAD_COND_WAIT_POST ( ThreadId tid,
2388                                             void* cond, void* mutex,
2389                                             Bool timeout)
2390{
2391   /* A pthread_cond_wait(cond, mutex) completed successfully.  Find
2392      the SO for this cond, and 'recv' from it so as to acquire a
2393      dependency edge back to the signaller/broadcaster. */
2394   Thread* thr;
2395   CVInfo* cvi;
2396
2397   if (SHOW_EVENTS >= 1)
2398      VG_(printf)("evh__HG_PTHREAD_COND_WAIT_POST"
2399                  "(ctid=%d, cond=%p, mutex=%p)\n, timeout=%d",
2400                  (Int)tid, (void*)cond, (void*)mutex, (Int)timeout );
2401
2402   thr = map_threads_maybe_lookup( tid );
2403   tl_assert(thr); /* cannot fail - Thread* must already exist */
2404
2405   // error-if: cond is also associated with a different mutex
2406
2407   cvi = map_cond_to_CVInfo_lookup_NO_alloc( cond );
2408   if (!cvi) {
2409      /* This could be either a bug in helgrind or the guest application
2410         that did an error (e.g. cond var was destroyed by another thread.
2411         Let's assume helgrind is perfect ...
2412         Note that this is similar to drd behaviour. */
2413      HG_(record_error_Misc)(thr, "condition variable has been destroyed while"
2414                             " being waited upon");
2415      return;
2416   }
2417
2418   tl_assert(cvi);
2419   tl_assert(cvi->so);
2420   tl_assert(cvi->nWaiters > 0);
2421
2422   if (!timeout && !libhb_so_everSent(cvi->so)) {
2423      /* Hmm.  How can a wait on 'cond' succeed if nobody signalled
2424         it?  If this happened it would surely be a bug in the threads
2425         library.  Or one of those fabled "spurious wakeups". */
2426      HG_(record_error_Misc)( thr, "Bug in libpthread: pthread_cond_wait "
2427                                   "succeeded"
2428                                   " without prior pthread_cond_post");
2429   }
2430
2431   /* anyway, acquire a dependency on it. */
2432   libhb_so_recv( thr->hbthr, cvi->so, True/*strong_recv*/ );
2433
2434   cvi->nWaiters--;
2435}
2436
2437static void evh__HG_PTHREAD_COND_INIT_POST ( ThreadId tid,
2438                                             void* cond, void* cond_attr )
2439{
2440   CVInfo* cvi;
2441
2442   if (SHOW_EVENTS >= 1)
2443      VG_(printf)("evh__HG_PTHREAD_COND_INIT_POST"
2444                  "(ctid=%d, cond=%p, cond_attr=%p)\n",
2445                  (Int)tid, (void*)cond, (void*) cond_attr );
2446
2447   cvi = map_cond_to_CVInfo_lookup_or_alloc( cond );
2448   tl_assert (cvi);
2449   tl_assert (cvi->so);
2450}
2451
2452
2453static void evh__HG_PTHREAD_COND_DESTROY_PRE ( ThreadId tid,
2454                                               void* cond, Bool cond_is_init )
2455{
2456   /* Deal with destroy events.  The only purpose is to free storage
2457      associated with the CV, so as to avoid any possible resource
2458      leaks. */
2459   if (SHOW_EVENTS >= 1)
2460      VG_(printf)("evh__HG_PTHREAD_COND_DESTROY_PRE"
2461                  "(ctid=%d, cond=%p, cond_is_init=%d)\n",
2462                  (Int)tid, (void*)cond, (Int)cond_is_init );
2463
2464   map_cond_to_CVInfo_delete( tid, cond, cond_is_init );
2465}
2466
2467
2468/* ------------------------------------------------------- */
2469/* -------------- events to do with rwlocks -------------- */
2470/* ------------------------------------------------------- */
2471
2472/* EXPOSITION only */
2473static
2474void evh__HG_PTHREAD_RWLOCK_INIT_POST( ThreadId tid, void* rwl )
2475{
2476   if (SHOW_EVENTS >= 1)
2477      VG_(printf)("evh__hg_PTHREAD_RWLOCK_INIT_POST(ctid=%d, %p)\n",
2478                  (Int)tid, (void*)rwl );
2479   map_locks_lookup_or_create( LK_rdwr, (Addr)rwl, tid );
2480   if (HG_(clo_sanity_flags) & SCE_LOCKS)
2481      all__sanity_check("evh__hg_PTHREAD_RWLOCK_INIT_POST");
2482}
2483
2484static
2485void evh__HG_PTHREAD_RWLOCK_DESTROY_PRE( ThreadId tid, void* rwl )
2486{
2487   Thread* thr;
2488   Lock*   lk;
2489   if (SHOW_EVENTS >= 1)
2490      VG_(printf)("evh__hg_PTHREAD_RWLOCK_DESTROY_PRE(ctid=%d, %p)\n",
2491                  (Int)tid, (void*)rwl );
2492
2493   thr = map_threads_maybe_lookup( tid );
2494   /* cannot fail - Thread* must already exist */
2495   tl_assert( HG_(is_sane_Thread)(thr) );
2496
2497   lk = map_locks_maybe_lookup( (Addr)rwl );
2498
2499   if (lk == NULL || lk->kind != LK_rdwr) {
2500      HG_(record_error_Misc)(
2501         thr, "pthread_rwlock_destroy with invalid argument" );
2502   }
2503
2504   if (lk) {
2505      tl_assert( HG_(is_sane_LockN)(lk) );
2506      tl_assert( lk->guestaddr == (Addr)rwl );
2507      if (lk->heldBy) {
2508         /* Basically act like we unlocked the lock */
2509         HG_(record_error_Misc)(
2510            thr, "pthread_rwlock_destroy of a locked mutex" );
2511         /* remove lock from locksets of all owning threads */
2512         remove_Lock_from_locksets_of_all_owning_Threads( lk );
2513         VG_(deleteBag)( lk->heldBy );
2514         lk->heldBy = NULL;
2515         lk->heldW = False;
2516         lk->acquired_at = NULL;
2517      }
2518      tl_assert( !lk->heldBy );
2519      tl_assert( HG_(is_sane_LockN)(lk) );
2520
2521      if (HG_(clo_track_lockorders))
2522         laog__handle_one_lock_deletion(lk);
2523      map_locks_delete( lk->guestaddr );
2524      del_LockN( lk );
2525   }
2526
2527   if (HG_(clo_sanity_flags) & SCE_LOCKS)
2528      all__sanity_check("evh__hg_PTHREAD_RWLOCK_DESTROY_PRE");
2529}
2530
2531static
2532void evh__HG_PTHREAD_RWLOCK_LOCK_PRE ( ThreadId tid,
2533                                       void* rwl,
2534                                       Word isW, Word isTryLock )
2535{
2536   /* Just check the rwl is sane; nothing else to do. */
2537   // 'rwl' may be invalid - not checked by wrapper
2538   Thread* thr;
2539   Lock*   lk;
2540   if (SHOW_EVENTS >= 1)
2541      VG_(printf)("evh__hg_PTHREAD_RWLOCK_LOCK_PRE(ctid=%d, isW=%d, %p)\n",
2542                  (Int)tid, (Int)isW, (void*)rwl );
2543
2544   tl_assert(isW == 0 || isW == 1); /* assured us by wrapper */
2545   tl_assert(isTryLock == 0 || isTryLock == 1); /* assured us by wrapper */
2546   thr = map_threads_maybe_lookup( tid );
2547   tl_assert(thr); /* cannot fail - Thread* must already exist */
2548
2549   lk = map_locks_maybe_lookup( (Addr)rwl );
2550   if ( lk
2551        && (lk->kind == LK_nonRec || lk->kind == LK_mbRec) ) {
2552      /* Wrong kind of lock.  Duh.  */
2553      HG_(record_error_Misc)(
2554         thr, "pthread_rwlock_{rd,rw}lock with a "
2555              "pthread_mutex_t* argument " );
2556   }
2557}
2558
2559static
2560void evh__HG_PTHREAD_RWLOCK_LOCK_POST ( ThreadId tid, void* rwl, Word isW )
2561{
2562   // only called if the real library call succeeded - so mutex is sane
2563   Thread* thr;
2564   if (SHOW_EVENTS >= 1)
2565      VG_(printf)("evh__hg_PTHREAD_RWLOCK_LOCK_POST(ctid=%d, isW=%d, %p)\n",
2566                  (Int)tid, (Int)isW, (void*)rwl );
2567
2568   tl_assert(isW == 0 || isW == 1); /* assured us by wrapper */
2569   thr = map_threads_maybe_lookup( tid );
2570   tl_assert(thr); /* cannot fail - Thread* must already exist */
2571
2572   (isW ? evhH__post_thread_w_acquires_lock
2573        : evhH__post_thread_r_acquires_lock)(
2574      thr,
2575      LK_rdwr, /* if not known, create new lock with this LockKind */
2576      (Addr)rwl
2577   );
2578}
2579
2580static void evh__HG_PTHREAD_RWLOCK_UNLOCK_PRE ( ThreadId tid, void* rwl )
2581{
2582   // 'rwl' may be invalid - not checked by wrapper
2583   Thread* thr;
2584   if (SHOW_EVENTS >= 1)
2585      VG_(printf)("evh__HG_PTHREAD_RWLOCK_UNLOCK_PRE(ctid=%d, rwl=%p)\n",
2586                  (Int)tid, (void*)rwl );
2587
2588   thr = map_threads_maybe_lookup( tid );
2589   tl_assert(thr); /* cannot fail - Thread* must already exist */
2590
2591   evhH__pre_thread_releases_lock( thr, (Addr)rwl, True/*isRDWR*/ );
2592}
2593
2594static void evh__HG_PTHREAD_RWLOCK_UNLOCK_POST ( ThreadId tid, void* rwl )
2595{
2596   // only called if the real library call succeeded - so mutex is sane
2597   Thread* thr;
2598   if (SHOW_EVENTS >= 1)
2599      VG_(printf)("evh__hg_PTHREAD_RWLOCK_UNLOCK_POST(ctid=%d, rwl=%p)\n",
2600                  (Int)tid, (void*)rwl );
2601   thr = map_threads_maybe_lookup( tid );
2602   tl_assert(thr); /* cannot fail - Thread* must already exist */
2603
2604   // anything we should do here?
2605}
2606
2607
2608/* ---------------------------------------------------------- */
2609/* -------------- events to do with semaphores -------------- */
2610/* ---------------------------------------------------------- */
2611
2612/* This is similar to but not identical to the handling for condition
2613   variables. */
2614
2615/* For each semaphore, we maintain a stack of SOs.  When a 'post'
2616   operation is done on a semaphore (unlocking, essentially), a new SO
2617   is created for the posting thread, the posting thread does a strong
2618   send to it (which merely installs the posting thread's VC in the
2619   SO), and the SO is pushed on the semaphore's stack.
2620
2621   Later, when a (probably different) thread completes 'wait' on the
2622   semaphore, we pop a SO off the semaphore's stack (which should be
2623   nonempty), and do a strong recv from it.  This mechanism creates
2624   dependencies between posters and waiters of the semaphore.
2625
2626   It may not be necessary to use a stack - perhaps a bag of SOs would
2627   do.  But we do need to keep track of how many unused-up posts have
2628   happened for the semaphore.
2629
2630   Imagine T1 and T2 both post once on a semaphore S, and T3 waits
2631   twice on S.  T3 cannot complete its waits without both T1 and T2
2632   posting.  The above mechanism will ensure that T3 acquires
2633   dependencies on both T1 and T2.
2634
2635   When a semaphore is initialised with value N, we do as if we'd
2636   posted N times on the semaphore: basically create N SOs and do a
2637   strong send to all of then.  This allows up to N waits on the
2638   semaphore to acquire a dependency on the initialisation point,
2639   which AFAICS is the correct behaviour.
2640
2641   We don't emit an error for DESTROY_PRE on a semaphore we don't know
2642   about.  We should.
2643*/
2644
2645/* sem_t* -> XArray* SO* */
2646static WordFM* map_sem_to_SO_stack = NULL;
2647
2648static void map_sem_to_SO_stack_INIT ( void ) {
2649   if (map_sem_to_SO_stack == NULL) {
2650      map_sem_to_SO_stack = VG_(newFM)( HG_(zalloc), "hg.mstSs.1",
2651                                        HG_(free), NULL );
2652      tl_assert(map_sem_to_SO_stack != NULL);
2653   }
2654}
2655
2656static void push_SO_for_sem ( void* sem, SO* so ) {
2657   UWord   keyW;
2658   XArray* xa;
2659   tl_assert(so);
2660   map_sem_to_SO_stack_INIT();
2661   if (VG_(lookupFM)( map_sem_to_SO_stack,
2662                      &keyW, (UWord*)&xa, (UWord)sem )) {
2663      tl_assert(keyW == (UWord)sem);
2664      tl_assert(xa);
2665      VG_(addToXA)( xa, &so );
2666   } else {
2667     xa = VG_(newXA)( HG_(zalloc), "hg.pSfs.1", HG_(free), sizeof(SO*) );
2668      VG_(addToXA)( xa, &so );
2669      VG_(addToFM)( map_sem_to_SO_stack, (UWord)sem, (UWord)xa );
2670   }
2671}
2672
2673static SO* mb_pop_SO_for_sem ( void* sem ) {
2674   UWord    keyW;
2675   XArray*  xa;
2676   SO* so;
2677   map_sem_to_SO_stack_INIT();
2678   if (VG_(lookupFM)( map_sem_to_SO_stack,
2679                      &keyW, (UWord*)&xa, (UWord)sem )) {
2680      /* xa is the stack for this semaphore. */
2681      Word sz;
2682      tl_assert(keyW == (UWord)sem);
2683      sz = VG_(sizeXA)( xa );
2684      tl_assert(sz >= 0);
2685      if (sz == 0)
2686         return NULL; /* odd, the stack is empty */
2687      so = *(SO**)VG_(indexXA)( xa, sz-1 );
2688      tl_assert(so);
2689      VG_(dropTailXA)( xa, 1 );
2690      return so;
2691   } else {
2692      /* hmm, that's odd.  No stack for this semaphore. */
2693      return NULL;
2694   }
2695}
2696
2697static void evh__HG_POSIX_SEM_DESTROY_PRE ( ThreadId tid, void* sem )
2698{
2699   UWord keyW, valW;
2700   SO*   so;
2701
2702   if (SHOW_EVENTS >= 1)
2703      VG_(printf)("evh__HG_POSIX_SEM_DESTROY_PRE(ctid=%d, sem=%p)\n",
2704                  (Int)tid, (void*)sem );
2705
2706   map_sem_to_SO_stack_INIT();
2707
2708   /* Empty out the semaphore's SO stack.  This way of doing it is
2709      stupid, but at least it's easy. */
2710   while (1) {
2711      so = mb_pop_SO_for_sem( sem );
2712      if (!so) break;
2713      libhb_so_dealloc(so);
2714   }
2715
2716   if (VG_(delFromFM)( map_sem_to_SO_stack, &keyW, &valW, (UWord)sem )) {
2717      XArray* xa = (XArray*)valW;
2718      tl_assert(keyW == (UWord)sem);
2719      tl_assert(xa);
2720      tl_assert(VG_(sizeXA)(xa) == 0); /* preceding loop just emptied it */
2721      VG_(deleteXA)(xa);
2722   }
2723}
2724
2725static
2726void evh__HG_POSIX_SEM_INIT_POST ( ThreadId tid, void* sem, UWord value )
2727{
2728   SO*     so;
2729   Thread* thr;
2730
2731   if (SHOW_EVENTS >= 1)
2732      VG_(printf)("evh__HG_POSIX_SEM_INIT_POST(ctid=%d, sem=%p, value=%lu)\n",
2733                  (Int)tid, (void*)sem, value );
2734
2735   thr = map_threads_maybe_lookup( tid );
2736   tl_assert(thr); /* cannot fail - Thread* must already exist */
2737
2738   /* Empty out the semaphore's SO stack.  This way of doing it is
2739      stupid, but at least it's easy. */
2740   while (1) {
2741      so = mb_pop_SO_for_sem( sem );
2742      if (!so) break;
2743      libhb_so_dealloc(so);
2744   }
2745
2746   /* If we don't do this check, the following while loop runs us out
2747      of memory for stupid initial values of 'value'. */
2748   if (value > 10000) {
2749      HG_(record_error_Misc)(
2750         thr, "sem_init: initial value exceeds 10000; using 10000" );
2751      value = 10000;
2752   }
2753
2754   /* Now create 'valid' new SOs for the thread, do a strong send to
2755      each of them, and push them all on the stack. */
2756   for (; value > 0; value--) {
2757      Thr* hbthr = thr->hbthr;
2758      tl_assert(hbthr);
2759
2760      so = libhb_so_alloc();
2761      libhb_so_send( hbthr, so, True/*strong send*/ );
2762      push_SO_for_sem( sem, so );
2763   }
2764}
2765
2766static void evh__HG_POSIX_SEM_POST_PRE ( ThreadId tid, void* sem )
2767{
2768   /* 'tid' has posted on 'sem'.  Create a new SO, do a strong send to
2769      it (iow, write our VC into it, then tick ours), and push the SO
2770      on on a stack of SOs associated with 'sem'.  This is later used
2771      by other thread(s) which successfully exit from a sem_wait on
2772      the same sem; by doing a strong recv from SOs popped of the
2773      stack, they acquire dependencies on the posting thread
2774      segment(s). */
2775
2776   Thread* thr;
2777   SO*     so;
2778   Thr*    hbthr;
2779
2780   if (SHOW_EVENTS >= 1)
2781      VG_(printf)("evh__HG_POSIX_SEM_POST_PRE(ctid=%d, sem=%p)\n",
2782                  (Int)tid, (void*)sem );
2783
2784   thr = map_threads_maybe_lookup( tid );
2785   tl_assert(thr); /* cannot fail - Thread* must already exist */
2786
2787   // error-if: sem is bogus
2788
2789   hbthr = thr->hbthr;
2790   tl_assert(hbthr);
2791
2792   so = libhb_so_alloc();
2793   libhb_so_send( hbthr, so, True/*strong send*/ );
2794   push_SO_for_sem( sem, so );
2795}
2796
2797static void evh__HG_POSIX_SEM_WAIT_POST ( ThreadId tid, void* sem )
2798{
2799   /* A sem_wait(sem) completed successfully.  Pop the posting-SO for
2800      the 'sem' from this semaphore's SO-stack, and do a strong recv
2801      from it.  This creates a dependency back to one of the post-ers
2802      for the semaphore. */
2803
2804   Thread* thr;
2805   SO*     so;
2806   Thr*    hbthr;
2807
2808   if (SHOW_EVENTS >= 1)
2809      VG_(printf)("evh__HG_POSIX_SEM_WAIT_POST(ctid=%d, sem=%p)\n",
2810                  (Int)tid, (void*)sem );
2811
2812   thr = map_threads_maybe_lookup( tid );
2813   tl_assert(thr); /* cannot fail - Thread* must already exist */
2814
2815   // error-if: sem is bogus
2816
2817   so = mb_pop_SO_for_sem( sem );
2818
2819   if (so) {
2820      hbthr = thr->hbthr;
2821      tl_assert(hbthr);
2822
2823      libhb_so_recv( hbthr, so, True/*strong recv*/ );
2824      libhb_so_dealloc(so);
2825   } else {
2826      /* Hmm.  How can a wait on 'sem' succeed if nobody posted to it?
2827         If this happened it would surely be a bug in the threads
2828         library. */
2829      HG_(record_error_Misc)(
2830         thr, "Bug in libpthread: sem_wait succeeded on"
2831              " semaphore without prior sem_post");
2832   }
2833}
2834
2835
2836/* -------------------------------------------------------- */
2837/* -------------- events to do with barriers -------------- */
2838/* -------------------------------------------------------- */
2839
2840typedef
2841   struct {
2842      Bool    initted; /* has it yet been initted by guest? */
2843      Bool    resizable; /* is resizing allowed? */
2844      UWord   size;    /* declared size */
2845      XArray* waiting; /* XA of Thread*.  # present is 0 .. .size */
2846   }
2847   Bar;
2848
2849static Bar* new_Bar ( void ) {
2850   Bar* bar = HG_(zalloc)( "hg.nB.1 (new_Bar)", sizeof(Bar) );
2851   tl_assert(bar);
2852   /* all fields are zero */
2853   tl_assert(bar->initted == False);
2854   return bar;
2855}
2856
2857static void delete_Bar ( Bar* bar ) {
2858   tl_assert(bar);
2859   if (bar->waiting)
2860      VG_(deleteXA)(bar->waiting);
2861   HG_(free)(bar);
2862}
2863
2864/* A mapping which stores auxiliary data for barriers. */
2865
2866/* pthread_barrier_t* -> Bar* */
2867static WordFM* map_barrier_to_Bar = NULL;
2868
2869static void map_barrier_to_Bar_INIT ( void ) {
2870   if (UNLIKELY(map_barrier_to_Bar == NULL)) {
2871      map_barrier_to_Bar = VG_(newFM)( HG_(zalloc),
2872                                       "hg.mbtBI.1", HG_(free), NULL );
2873      tl_assert(map_barrier_to_Bar != NULL);
2874   }
2875}
2876
2877static Bar* map_barrier_to_Bar_lookup_or_alloc ( void* barrier ) {
2878   UWord key, val;
2879   map_barrier_to_Bar_INIT();
2880   if (VG_(lookupFM)( map_barrier_to_Bar, &key, &val, (UWord)barrier )) {
2881      tl_assert(key == (UWord)barrier);
2882      return (Bar*)val;
2883   } else {
2884      Bar* bar = new_Bar();
2885      VG_(addToFM)( map_barrier_to_Bar, (UWord)barrier, (UWord)bar );
2886      return bar;
2887   }
2888}
2889
2890static void map_barrier_to_Bar_delete ( void* barrier ) {
2891   UWord keyW, valW;
2892   map_barrier_to_Bar_INIT();
2893   if (VG_(delFromFM)( map_barrier_to_Bar, &keyW, &valW, (UWord)barrier )) {
2894      Bar* bar = (Bar*)valW;
2895      tl_assert(keyW == (UWord)barrier);
2896      delete_Bar(bar);
2897   }
2898}
2899
2900
2901static void evh__HG_PTHREAD_BARRIER_INIT_PRE ( ThreadId tid,
2902                                               void* barrier,
2903                                               UWord count,
2904                                               UWord resizable )
2905{
2906   Thread* thr;
2907   Bar*    bar;
2908
2909   if (SHOW_EVENTS >= 1)
2910      VG_(printf)("evh__HG_PTHREAD_BARRIER_INIT_PRE"
2911                  "(tid=%d, barrier=%p, count=%lu, resizable=%lu)\n",
2912                  (Int)tid, (void*)barrier, count, resizable );
2913
2914   thr = map_threads_maybe_lookup( tid );
2915   tl_assert(thr); /* cannot fail - Thread* must already exist */
2916
2917   if (count == 0) {
2918      HG_(record_error_Misc)(
2919         thr, "pthread_barrier_init: 'count' argument is zero"
2920      );
2921   }
2922
2923   if (resizable != 0 && resizable != 1) {
2924      HG_(record_error_Misc)(
2925         thr, "pthread_barrier_init: invalid 'resizable' argument"
2926      );
2927   }
2928
2929   bar = map_barrier_to_Bar_lookup_or_alloc(barrier);
2930   tl_assert(bar);
2931
2932   if (bar->initted) {
2933      HG_(record_error_Misc)(
2934         thr, "pthread_barrier_init: barrier is already initialised"
2935      );
2936   }
2937
2938   if (bar->waiting && VG_(sizeXA)(bar->waiting) > 0) {
2939      tl_assert(bar->initted);
2940      HG_(record_error_Misc)(
2941         thr, "pthread_barrier_init: threads are waiting at barrier"
2942      );
2943      VG_(dropTailXA)(bar->waiting, VG_(sizeXA)(bar->waiting));
2944   }
2945   if (!bar->waiting) {
2946      bar->waiting = VG_(newXA)( HG_(zalloc), "hg.eHPBIP.1", HG_(free),
2947                                 sizeof(Thread*) );
2948   }
2949
2950   tl_assert(bar->waiting);
2951   tl_assert(VG_(sizeXA)(bar->waiting) == 0);
2952   bar->initted   = True;
2953   bar->resizable = resizable == 1 ? True : False;
2954   bar->size      = count;
2955}
2956
2957
2958static void evh__HG_PTHREAD_BARRIER_DESTROY_PRE ( ThreadId tid,
2959                                                  void* barrier )
2960{
2961   Thread* thr;
2962   Bar*    bar;
2963
2964   /* Deal with destroy events.  The only purpose is to free storage
2965      associated with the barrier, so as to avoid any possible
2966      resource leaks. */
2967   if (SHOW_EVENTS >= 1)
2968      VG_(printf)("evh__HG_PTHREAD_BARRIER_DESTROY_PRE"
2969                  "(tid=%d, barrier=%p)\n",
2970                  (Int)tid, (void*)barrier );
2971
2972   thr = map_threads_maybe_lookup( tid );
2973   tl_assert(thr); /* cannot fail - Thread* must already exist */
2974
2975   bar = map_barrier_to_Bar_lookup_or_alloc(barrier);
2976   tl_assert(bar);
2977
2978   if (!bar->initted) {
2979      HG_(record_error_Misc)(
2980         thr, "pthread_barrier_destroy: barrier was never initialised"
2981      );
2982   }
2983
2984   if (bar->initted && bar->waiting && VG_(sizeXA)(bar->waiting) > 0) {
2985      HG_(record_error_Misc)(
2986         thr, "pthread_barrier_destroy: threads are waiting at barrier"
2987      );
2988   }
2989
2990   /* Maybe we shouldn't do this; just let it persist, so that when it
2991      is reinitialised we don't need to do any dynamic memory
2992      allocation?  The downside is a potentially unlimited space leak,
2993      if the client creates (in turn) a large number of barriers all
2994      at different locations.  Note that if we do later move to the
2995      don't-delete-it scheme, we need to mark the barrier as
2996      uninitialised again since otherwise a later _init call will
2997      elicit a duplicate-init error.  */
2998   map_barrier_to_Bar_delete( barrier );
2999}
3000
3001
3002/* All the threads have arrived.  Now do the Interesting Bit.  Get a
3003   new synchronisation object and do a weak send to it from all the
3004   participating threads.  This makes its vector clocks be the join of
3005   all the individual threads' vector clocks.  Then do a strong
3006   receive from it back to all threads, so that their VCs are a copy
3007   of it (hence are all equal to the join of their original VCs.) */
3008static void do_barrier_cross_sync_and_empty ( Bar* bar )
3009{
3010   /* XXX check bar->waiting has no duplicates */
3011   UWord i;
3012   SO*   so = libhb_so_alloc();
3013
3014   tl_assert(bar->waiting);
3015   tl_assert(VG_(sizeXA)(bar->waiting) == bar->size);
3016
3017   /* compute the join ... */
3018   for (i = 0; i < bar->size; i++) {
3019      Thread* t = *(Thread**)VG_(indexXA)(bar->waiting, i);
3020      Thr* hbthr = t->hbthr;
3021      libhb_so_send( hbthr, so, False/*weak send*/ );
3022   }
3023   /* ... and distribute to all threads */
3024   for (i = 0; i < bar->size; i++) {
3025      Thread* t = *(Thread**)VG_(indexXA)(bar->waiting, i);
3026      Thr* hbthr = t->hbthr;
3027      libhb_so_recv( hbthr, so, True/*strong recv*/ );
3028   }
3029
3030   /* finally, we must empty out the waiting vector */
3031   VG_(dropTailXA)(bar->waiting, VG_(sizeXA)(bar->waiting));
3032
3033   /* and we don't need this any more.  Perhaps a stack-allocated
3034      SO would be better? */
3035   libhb_so_dealloc(so);
3036}
3037
3038
3039static void evh__HG_PTHREAD_BARRIER_WAIT_PRE ( ThreadId tid,
3040                                               void* barrier )
3041{
3042  /* This function gets called after a client thread calls
3043     pthread_barrier_wait but before it arrives at the real
3044     pthread_barrier_wait.
3045
3046     Why is the following correct?  It's a bit subtle.
3047
3048     If this is not the last thread arriving at the barrier, we simply
3049     note its presence and return.  Because valgrind (at least as of
3050     Nov 08) is single threaded, we are guaranteed safe from any race
3051     conditions when in this function -- no other client threads are
3052     running.
3053
3054     If this is the last thread, then we are again the only running
3055     thread.  All the other threads will have either arrived at the
3056     real pthread_barrier_wait or are on their way to it, but in any
3057     case are guaranteed not to be able to move past it, because this
3058     thread is currently in this function and so has not yet arrived
3059     at the real pthread_barrier_wait.  That means that:
3060
3061     1. While we are in this function, none of the other threads
3062        waiting at the barrier can move past it.
3063
3064     2. When this function returns (and simulated execution resumes),
3065        this thread and all other waiting threads will be able to move
3066        past the real barrier.
3067
3068     Because of this, it is now safe to update the vector clocks of
3069     all threads, to represent the fact that they all arrived at the
3070     barrier and have all moved on.  There is no danger of any
3071     complications to do with some threads leaving the barrier and
3072     racing back round to the front, whilst others are still leaving
3073     (which is the primary source of complication in correct handling/
3074     implementation of barriers).  That can't happen because we update
3075     here our data structures so as to indicate that the threads have
3076     passed the barrier, even though, as per (2) above, they are
3077     guaranteed not to pass the barrier until we return.
3078
3079     This relies crucially on Valgrind being single threaded.  If that
3080     changes, this will need to be reconsidered.
3081   */
3082   Thread* thr;
3083   Bar*    bar;
3084   UWord   present;
3085
3086   if (SHOW_EVENTS >= 1)
3087      VG_(printf)("evh__HG_PTHREAD_BARRIER_WAIT_PRE"
3088                  "(tid=%d, barrier=%p)\n",
3089                  (Int)tid, (void*)barrier );
3090
3091   thr = map_threads_maybe_lookup( tid );
3092   tl_assert(thr); /* cannot fail - Thread* must already exist */
3093
3094   bar = map_barrier_to_Bar_lookup_or_alloc(barrier);
3095   tl_assert(bar);
3096
3097   if (!bar->initted) {
3098      HG_(record_error_Misc)(
3099         thr, "pthread_barrier_wait: barrier is uninitialised"
3100      );
3101      return; /* client is broken .. avoid assertions below */
3102   }
3103
3104   /* guaranteed by _INIT_PRE above */
3105   tl_assert(bar->size > 0);
3106   tl_assert(bar->waiting);
3107
3108   VG_(addToXA)( bar->waiting, &thr );
3109
3110   /* guaranteed by this function */
3111   present = VG_(sizeXA)(bar->waiting);
3112   tl_assert(present > 0 && present <= bar->size);
3113
3114   if (present < bar->size)
3115      return;
3116
3117   do_barrier_cross_sync_and_empty(bar);
3118}
3119
3120
3121static void evh__HG_PTHREAD_BARRIER_RESIZE_PRE ( ThreadId tid,
3122                                                 void* barrier,
3123                                                 UWord newcount )
3124{
3125   Thread* thr;
3126   Bar*    bar;
3127   UWord   present;
3128
3129   if (SHOW_EVENTS >= 1)
3130      VG_(printf)("evh__HG_PTHREAD_BARRIER_RESIZE_PRE"
3131                  "(tid=%d, barrier=%p, newcount=%lu)\n",
3132                  (Int)tid, (void*)barrier, newcount );
3133
3134   thr = map_threads_maybe_lookup( tid );
3135   tl_assert(thr); /* cannot fail - Thread* must already exist */
3136
3137   bar = map_barrier_to_Bar_lookup_or_alloc(barrier);
3138   tl_assert(bar);
3139
3140   if (!bar->initted) {
3141      HG_(record_error_Misc)(
3142         thr, "pthread_barrier_resize: barrier is uninitialised"
3143      );
3144      return; /* client is broken .. avoid assertions below */
3145   }
3146
3147   if (!bar->resizable) {
3148      HG_(record_error_Misc)(
3149         thr, "pthread_barrier_resize: barrier is may not be resized"
3150      );
3151      return; /* client is broken .. avoid assertions below */
3152   }
3153
3154   if (newcount == 0) {
3155      HG_(record_error_Misc)(
3156         thr, "pthread_barrier_resize: 'newcount' argument is zero"
3157      );
3158      return; /* client is broken .. avoid assertions below */
3159   }
3160
3161   /* guaranteed by _INIT_PRE above */
3162   tl_assert(bar->size > 0);
3163   tl_assert(bar->waiting);
3164   /* Guaranteed by this fn */
3165   tl_assert(newcount > 0);
3166
3167   if (newcount >= bar->size) {
3168      /* Increasing the capacity.  There's no possibility of threads
3169         moving on from the barrier in this situation, so just note
3170         the fact and do nothing more. */
3171      bar->size = newcount;
3172   } else {
3173      /* Decreasing the capacity.  If we decrease it to be equal or
3174         below the number of waiting threads, they will now move past
3175         the barrier, so need to mess with dep edges in the same way
3176         as if the barrier had filled up normally. */
3177      present = VG_(sizeXA)(bar->waiting);
3178      tl_assert(present >= 0 && present <= bar->size);
3179      if (newcount <= present) {
3180         bar->size = present; /* keep the cross_sync call happy */
3181         do_barrier_cross_sync_and_empty(bar);
3182      }
3183      bar->size = newcount;
3184   }
3185}
3186
3187
3188/* ----------------------------------------------------- */
3189/* ----- events to do with user-specified HB edges ----- */
3190/* ----------------------------------------------------- */
3191
3192/* A mapping from arbitrary UWord tag to the SO associated with it.
3193   The UWord tags are meaningless to us, interpreted only by the
3194   user. */
3195
3196
3197
3198/* UWord -> SO* */
3199static WordFM* map_usertag_to_SO = NULL;
3200
3201static void map_usertag_to_SO_INIT ( void ) {
3202   if (UNLIKELY(map_usertag_to_SO == NULL)) {
3203      map_usertag_to_SO = VG_(newFM)( HG_(zalloc),
3204                                      "hg.mutS.1", HG_(free), NULL );
3205      tl_assert(map_usertag_to_SO != NULL);
3206   }
3207}
3208
3209static SO* map_usertag_to_SO_lookup_or_alloc ( UWord usertag ) {
3210   UWord key, val;
3211   map_usertag_to_SO_INIT();
3212   if (VG_(lookupFM)( map_usertag_to_SO, &key, &val, usertag )) {
3213      tl_assert(key == (UWord)usertag);
3214      return (SO*)val;
3215   } else {
3216      SO* so = libhb_so_alloc();
3217      VG_(addToFM)( map_usertag_to_SO, usertag, (UWord)so );
3218      return so;
3219   }
3220}
3221
3222static void map_usertag_to_SO_delete ( UWord usertag ) {
3223   UWord keyW, valW;
3224   map_usertag_to_SO_INIT();
3225   if (VG_(delFromFM)( map_usertag_to_SO, &keyW, &valW, usertag )) {
3226      SO* so = (SO*)valW;
3227      tl_assert(keyW == usertag);
3228      tl_assert(so);
3229      libhb_so_dealloc(so);
3230   }
3231}
3232
3233
3234static
3235void evh__HG_USERSO_SEND_PRE ( ThreadId tid, UWord usertag )
3236{
3237   /* TID is just about to notionally sent a message on a notional
3238      abstract synchronisation object whose identity is given by
3239      USERTAG.  Bind USERTAG to a real SO if it is not already so
3240      bound, and do a 'weak send' on the SO.  This joins the vector
3241      clocks from this thread into any vector clocks already present
3242      in the SO.  The resulting SO vector clocks are later used by
3243      other thread(s) which successfully 'receive' from the SO,
3244      thereby acquiring a dependency on all the events that have
3245      previously signalled on this SO. */
3246   Thread* thr;
3247   SO*     so;
3248
3249   if (SHOW_EVENTS >= 1)
3250      VG_(printf)("evh__HG_USERSO_SEND_PRE(ctid=%d, usertag=%#lx)\n",
3251                  (Int)tid, usertag );
3252
3253   thr = map_threads_maybe_lookup( tid );
3254   tl_assert(thr); /* cannot fail - Thread* must already exist */
3255
3256   so = map_usertag_to_SO_lookup_or_alloc( usertag );
3257   tl_assert(so);
3258
3259   libhb_so_send( thr->hbthr, so, False/*!strong_send*/ );
3260}
3261
3262static
3263void evh__HG_USERSO_RECV_POST ( ThreadId tid, UWord usertag )
3264{
3265   /* TID has just notionally received a message from a notional
3266      abstract synchronisation object whose identity is given by
3267      USERTAG.  Bind USERTAG to a real SO if it is not already so
3268      bound.  If the SO has at some point in the past been 'sent' on,
3269      to a 'strong receive' on it, thereby acquiring a dependency on
3270      the sender. */
3271   Thread* thr;
3272   SO*     so;
3273
3274   if (SHOW_EVENTS >= 1)
3275      VG_(printf)("evh__HG_USERSO_RECV_POST(ctid=%d, usertag=%#lx)\n",
3276                  (Int)tid, usertag );
3277
3278   thr = map_threads_maybe_lookup( tid );
3279   tl_assert(thr); /* cannot fail - Thread* must already exist */
3280
3281   so = map_usertag_to_SO_lookup_or_alloc( usertag );
3282   tl_assert(so);
3283
3284   /* Acquire a dependency on it.  If the SO has never so far been
3285      sent on, then libhb_so_recv will do nothing.  So we're safe
3286      regardless of SO's history. */
3287   libhb_so_recv( thr->hbthr, so, True/*strong_recv*/ );
3288}
3289
3290static
3291void evh__HG_USERSO_FORGET_ALL ( ThreadId tid, UWord usertag )
3292{
3293   /* TID declares that any happens-before edges notionally stored in
3294      USERTAG can be deleted.  If (as would normally be the case) a
3295      SO is associated with USERTAG, then the assocation is removed
3296      and all resources associated with SO are freed.  Importantly,
3297      that frees up any VTSs stored in SO. */
3298   if (SHOW_EVENTS >= 1)
3299      VG_(printf)("evh__HG_USERSO_FORGET_ALL(ctid=%d, usertag=%#lx)\n",
3300                  (Int)tid, usertag );
3301
3302   map_usertag_to_SO_delete( usertag );
3303}
3304
3305
3306/*--------------------------------------------------------------*/
3307/*--- Lock acquisition order monitoring                      ---*/
3308/*--------------------------------------------------------------*/
3309
3310/* FIXME: here are some optimisations still to do in
3311          laog__pre_thread_acquires_lock.
3312
3313   The graph is structured so that if L1 --*--> L2 then L1 must be
3314   acquired before L2.
3315
3316   The common case is that some thread T holds (eg) L1 L2 and L3 and
3317   is repeatedly acquiring and releasing Ln, and there is no ordering
3318   error in what it is doing.  Hence it repeatly:
3319
3320   (1) searches laog to see if Ln --*--> {L1,L2,L3}, which always
3321       produces the answer No (because there is no error).
3322
3323   (2) adds edges {L1,L2,L3} --> Ln to laog, which are already present
3324       (because they already got added the first time T acquired Ln).
3325
3326   Hence cache these two events:
3327
3328   (1) Cache result of the query from last time.  Invalidate the cache
3329       any time any edges are added to or deleted from laog.
3330
3331   (2) Cache these add-edge requests and ignore them if said edges
3332       have already been added to laog.  Invalidate the cache any time
3333       any edges are deleted from laog.
3334*/
3335
3336typedef
3337   struct {
3338      WordSetID inns; /* in univ_laog */
3339      WordSetID outs; /* in univ_laog */
3340   }
3341   LAOGLinks;
3342
3343/* lock order acquisition graph */
3344static WordFM* laog = NULL; /* WordFM Lock* LAOGLinks* */
3345
3346/* EXPOSITION ONLY: for each edge in 'laog', record the two places
3347   where that edge was created, so that we can show the user later if
3348   we need to. */
3349typedef
3350   struct {
3351      Addr        src_ga; /* Lock guest addresses for */
3352      Addr        dst_ga; /* src/dst of the edge */
3353      ExeContext* src_ec; /* And corresponding places where that */
3354      ExeContext* dst_ec; /* ordering was established */
3355   }
3356   LAOGLinkExposition;
3357
3358static Word cmp_LAOGLinkExposition ( UWord llx1W, UWord llx2W ) {
3359   /* Compare LAOGLinkExposition*s by (src_ga,dst_ga) field pair. */
3360   LAOGLinkExposition* llx1 = (LAOGLinkExposition*)llx1W;
3361   LAOGLinkExposition* llx2 = (LAOGLinkExposition*)llx2W;
3362   if (llx1->src_ga < llx2->src_ga) return -1;
3363   if (llx1->src_ga > llx2->src_ga) return  1;
3364   if (llx1->dst_ga < llx2->dst_ga) return -1;
3365   if (llx1->dst_ga > llx2->dst_ga) return  1;
3366   return 0;
3367}
3368
3369static WordFM* laog_exposition = NULL; /* WordFM LAOGLinkExposition* NULL */
3370/* end EXPOSITION ONLY */
3371
3372
3373__attribute__((noinline))
3374static void laog__init ( void )
3375{
3376   tl_assert(!laog);
3377   tl_assert(!laog_exposition);
3378   tl_assert(HG_(clo_track_lockorders));
3379
3380   laog = VG_(newFM)( HG_(zalloc), "hg.laog__init.1",
3381                      HG_(free), NULL/*unboxedcmp*/ );
3382
3383   laog_exposition = VG_(newFM)( HG_(zalloc), "hg.laog__init.2", HG_(free),
3384                                 cmp_LAOGLinkExposition );
3385   tl_assert(laog);
3386   tl_assert(laog_exposition);
3387}
3388
3389static void laog__show ( const HChar* who ) {
3390   UWord i, ws_size;
3391   UWord* ws_words;
3392   Lock* me;
3393   LAOGLinks* links;
3394   VG_(printf)("laog (requested by %s) {\n", who);
3395   VG_(initIterFM)( laog );
3396   me = NULL;
3397   links = NULL;
3398   while (VG_(nextIterFM)( laog, (UWord*)&me,
3399                                 (UWord*)&links )) {
3400      tl_assert(me);
3401      tl_assert(links);
3402      VG_(printf)("   node %p:\n", me);
3403      HG_(getPayloadWS)( &ws_words, &ws_size, univ_laog, links->inns );
3404      for (i = 0; i < ws_size; i++)
3405         VG_(printf)("      inn %#lx\n", ws_words[i] );
3406      HG_(getPayloadWS)( &ws_words, &ws_size, univ_laog, links->outs );
3407      for (i = 0; i < ws_size; i++)
3408         VG_(printf)("      out %#lx\n", ws_words[i] );
3409      me = NULL;
3410      links = NULL;
3411   }
3412   VG_(doneIterFM)( laog );
3413   VG_(printf)("}\n");
3414}
3415
3416static void univ_laog_do_GC ( void ) {
3417   Word i;
3418   LAOGLinks* links;
3419   Word seen = 0;
3420   Int prev_next_gc_univ_laog = next_gc_univ_laog;
3421   const UWord univ_laog_cardinality = HG_(cardinalityWSU)( univ_laog);
3422
3423   Bool *univ_laog_seen = HG_(zalloc) ( "hg.gc_univ_laog.1",
3424                                        (Int) univ_laog_cardinality
3425                                        * sizeof(Bool) );
3426   // univ_laog_seen[*] set to 0 (False) by zalloc.
3427
3428   if (VG_(clo_stats))
3429      VG_(message)(Vg_DebugMsg,
3430                   "univ_laog_do_GC enter cardinality %'10d\n",
3431                   (Int)univ_laog_cardinality);
3432
3433   VG_(initIterFM)( laog );
3434   links = NULL;
3435   while (VG_(nextIterFM)( laog, NULL, (UWord*)&links )) {
3436      tl_assert(links);
3437      tl_assert(links->inns >= 0 && links->inns < univ_laog_cardinality);
3438      univ_laog_seen[links->inns] = True;
3439      tl_assert(links->outs >= 0 && links->outs < univ_laog_cardinality);
3440      univ_laog_seen[links->outs] = True;
3441      links = NULL;
3442   }
3443   VG_(doneIterFM)( laog );
3444
3445   for (i = 0; i < (Int)univ_laog_cardinality; i++) {
3446      if (univ_laog_seen[i])
3447         seen++;
3448      else
3449         HG_(dieWS) ( univ_laog, (WordSet)i );
3450   }
3451
3452   HG_(free) (univ_laog_seen);
3453
3454   // We need to decide the value of the next_gc.
3455   // 3 solutions were looked at:
3456   // Sol 1: garbage collect at seen * 2
3457   //   This solution was a lot slower, probably because we both do a lot of
3458   //   garbage collection and do not keep long enough laog WV that will become
3459   //   useful  again very soon.
3460   // Sol 2: garbage collect at a percentage increase of the current cardinality
3461   //         (with a min increase of 1)
3462   //   Trials on a small test program with 1%, 5% and 10% increase was done.
3463   //   1% is slightly faster than 5%, which is slightly slower than 10%.
3464   //   However, on a big application, this caused the memory to be exhausted,
3465   //   as even a 1% increase of size at each gc becomes a lot, when many gc
3466   //   are done.
3467   // Sol 3: always garbage collect at current cardinality + 1.
3468   //   This solution was the fastest of the 3 solutions, and caused no memory
3469   //   exhaustion in the big application.
3470   //
3471   // With regards to cost introduced by gc: on the t2t perf test (doing only
3472   // lock/unlock operations), t2t 50 10 2 was about 25% faster than the
3473   // version with garbage collection. With t2t 50 20 2, my machine started
3474   // to page out, and so the garbage collected version was much faster.
3475   // On smaller lock sets (e.g. t2t 20 5 2, giving about 100 locks), the
3476   // difference performance is insignificant (~ 0.1 s).
3477   // Of course, it might be that real life programs are not well represented
3478   // by t2t.
3479
3480   // If ever we want to have a more sophisticated control
3481   // (e.g. clo options to control the percentage increase or fixed increased),
3482   // we should do it here, eg.
3483   //     next_gc_univ_laog = prev_next_gc_univ_laog + VG_(clo_laog_gc_fixed);
3484   // Currently, we just hard-code the solution 3 above.
3485   next_gc_univ_laog = prev_next_gc_univ_laog + 1;
3486
3487   if (VG_(clo_stats))
3488      VG_(message)
3489         (Vg_DebugMsg,
3490          "univ_laog_do_GC exit seen %'8d next gc at cardinality %'10d\n",
3491          (Int)seen, next_gc_univ_laog);
3492}
3493
3494
3495__attribute__((noinline))
3496static void laog__add_edge ( Lock* src, Lock* dst ) {
3497   UWord      keyW;
3498   LAOGLinks* links;
3499   Bool       presentF, presentR;
3500   if (0) VG_(printf)("laog__add_edge %p %p\n", src, dst);
3501
3502   /* Take the opportunity to sanity check the graph.  Record in
3503      presentF if there is already a src->dst mapping in this node's
3504      forwards links, and presentR if there is already a src->dst
3505      mapping in this node's backwards links.  They should agree!
3506      Also, we need to know whether the edge was already present so as
3507      to decide whether or not to update the link details mapping.  We
3508      can compute presentF and presentR essentially for free, so may
3509      as well do this always. */
3510   presentF = presentR = False;
3511
3512   /* Update the out edges for src */
3513   keyW  = 0;
3514   links = NULL;
3515   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)src )) {
3516      WordSetID outs_new;
3517      tl_assert(links);
3518      tl_assert(keyW == (UWord)src);
3519      outs_new = HG_(addToWS)( univ_laog, links->outs, (UWord)dst );
3520      presentF = outs_new == links->outs;
3521      links->outs = outs_new;
3522   } else {
3523      links = HG_(zalloc)("hg.lae.1", sizeof(LAOGLinks));
3524      links->inns = HG_(emptyWS)( univ_laog );
3525      links->outs = HG_(singletonWS)( univ_laog, (UWord)dst );
3526      VG_(addToFM)( laog, (UWord)src, (UWord)links );
3527   }
3528   /* Update the in edges for dst */
3529   keyW  = 0;
3530   links = NULL;
3531   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)dst )) {
3532      WordSetID inns_new;
3533      tl_assert(links);
3534      tl_assert(keyW == (UWord)dst);
3535      inns_new = HG_(addToWS)( univ_laog, links->inns, (UWord)src );
3536      presentR = inns_new == links->inns;
3537      links->inns = inns_new;
3538   } else {
3539      links = HG_(zalloc)("hg.lae.2", sizeof(LAOGLinks));
3540      links->inns = HG_(singletonWS)( univ_laog, (UWord)src );
3541      links->outs = HG_(emptyWS)( univ_laog );
3542      VG_(addToFM)( laog, (UWord)dst, (UWord)links );
3543   }
3544
3545   tl_assert( (presentF && presentR) || (!presentF && !presentR) );
3546
3547   if (!presentF && src->acquired_at && dst->acquired_at) {
3548      LAOGLinkExposition expo;
3549      /* If this edge is entering the graph, and we have acquired_at
3550         information for both src and dst, record those acquisition
3551         points.  Hence, if there is later a violation of this
3552         ordering, we can show the user the two places in which the
3553         required src-dst ordering was previously established. */
3554      if (0) VG_(printf)("acquire edge %#lx %#lx\n",
3555                         src->guestaddr, dst->guestaddr);
3556      expo.src_ga = src->guestaddr;
3557      expo.dst_ga = dst->guestaddr;
3558      expo.src_ec = NULL;
3559      expo.dst_ec = NULL;
3560      tl_assert(laog_exposition);
3561      if (VG_(lookupFM)( laog_exposition, NULL, NULL, (UWord)&expo )) {
3562         /* we already have it; do nothing */
3563      } else {
3564         LAOGLinkExposition* expo2 = HG_(zalloc)("hg.lae.3",
3565                                               sizeof(LAOGLinkExposition));
3566         expo2->src_ga = src->guestaddr;
3567         expo2->dst_ga = dst->guestaddr;
3568         expo2->src_ec = src->acquired_at;
3569         expo2->dst_ec = dst->acquired_at;
3570         VG_(addToFM)( laog_exposition, (UWord)expo2, (UWord)NULL );
3571      }
3572   }
3573
3574   if (HG_(cardinalityWSU) (univ_laog) >= next_gc_univ_laog)
3575      univ_laog_do_GC();
3576}
3577
3578__attribute__((noinline))
3579static void laog__del_edge ( Lock* src, Lock* dst ) {
3580   UWord      keyW;
3581   LAOGLinks* links;
3582   if (0) VG_(printf)("laog__del_edge enter %p %p\n", src, dst);
3583   /* Update the out edges for src */
3584   keyW  = 0;
3585   links = NULL;
3586   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)src )) {
3587      tl_assert(links);
3588      tl_assert(keyW == (UWord)src);
3589      links->outs = HG_(delFromWS)( univ_laog, links->outs, (UWord)dst );
3590   }
3591   /* Update the in edges for dst */
3592   keyW  = 0;
3593   links = NULL;
3594   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)dst )) {
3595      tl_assert(links);
3596      tl_assert(keyW == (UWord)dst);
3597      links->inns = HG_(delFromWS)( univ_laog, links->inns, (UWord)src );
3598   }
3599
3600   /* Remove the exposition of src,dst (if present) */
3601   {
3602      LAOGLinkExposition *fm_expo;
3603
3604      LAOGLinkExposition expo;
3605      expo.src_ga = src->guestaddr;
3606      expo.dst_ga = dst->guestaddr;
3607      expo.src_ec = NULL;
3608      expo.dst_ec = NULL;
3609
3610      if (VG_(delFromFM) (laog_exposition,
3611                          (UWord*)&fm_expo, NULL, (UWord)&expo )) {
3612         HG_(free) (fm_expo);
3613      }
3614   }
3615
3616   /* deleting edges can increase nr of of WS so check for gc. */
3617   if (HG_(cardinalityWSU) (univ_laog) >= next_gc_univ_laog)
3618      univ_laog_do_GC();
3619   if (0) VG_(printf)("laog__del_edge exit\n");
3620}
3621
3622__attribute__((noinline))
3623static WordSetID /* in univ_laog */ laog__succs ( Lock* lk ) {
3624   UWord      keyW;
3625   LAOGLinks* links;
3626   keyW  = 0;
3627   links = NULL;
3628   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)lk )) {
3629      tl_assert(links);
3630      tl_assert(keyW == (UWord)lk);
3631      return links->outs;
3632   } else {
3633      return HG_(emptyWS)( univ_laog );
3634   }
3635}
3636
3637__attribute__((noinline))
3638static WordSetID /* in univ_laog */ laog__preds ( Lock* lk ) {
3639   UWord      keyW;
3640   LAOGLinks* links;
3641   keyW  = 0;
3642   links = NULL;
3643   if (VG_(lookupFM)( laog, &keyW, (UWord*)&links, (UWord)lk )) {
3644      tl_assert(links);
3645      tl_assert(keyW == (UWord)lk);
3646      return links->inns;
3647   } else {
3648      return HG_(emptyWS)( univ_laog );
3649   }
3650}
3651
3652__attribute__((noinline))
3653static void laog__sanity_check ( const HChar* who ) {
3654   UWord i, ws_size;
3655   UWord* ws_words;
3656   Lock* me;
3657   LAOGLinks* links;
3658   VG_(initIterFM)( laog );
3659   me = NULL;
3660   links = NULL;
3661   if (0) VG_(printf)("laog sanity check\n");
3662   while (VG_(nextIterFM)( laog, (UWord*)&me,
3663                                 (UWord*)&links )) {
3664      tl_assert(me);
3665      tl_assert(links);
3666      HG_(getPayloadWS)( &ws_words, &ws_size, univ_laog, links->inns );
3667      for (i = 0; i < ws_size; i++) {
3668         if ( ! HG_(elemWS)( univ_laog,
3669                             laog__succs( (Lock*)ws_words[i] ),
3670                             (UWord)me ))
3671            goto bad;
3672      }
3673      HG_(getPayloadWS)( &ws_words, &ws_size, univ_laog, links->outs );
3674      for (i = 0; i < ws_size; i++) {
3675         if ( ! HG_(elemWS)( univ_laog,
3676                             laog__preds( (Lock*)ws_words[i] ),
3677                             (UWord)me ))
3678            goto bad;
3679      }
3680      me = NULL;
3681      links = NULL;
3682   }
3683   VG_(doneIterFM)( laog );
3684   return;
3685
3686  bad:
3687   VG_(printf)("laog__sanity_check(%s) FAILED\n", who);
3688   laog__show(who);
3689   tl_assert(0);
3690}
3691
3692/* If there is a path in laog from 'src' to any of the elements in
3693   'dst', return an arbitrarily chosen element of 'dst' reachable from
3694   'src'.  If no path exist from 'src' to any element in 'dst', return
3695   NULL. */
3696__attribute__((noinline))
3697static
3698Lock* laog__do_dfs_from_to ( Lock* src, WordSetID dsts /* univ_lsets */ )
3699{
3700   Lock*     ret;
3701   Word      ssz;
3702   XArray*   stack;   /* of Lock* */
3703   WordFM*   visited; /* Lock* -> void, iow, Set(Lock*) */
3704   Lock*     here;
3705   WordSetID succs;
3706   UWord     succs_size, i;
3707   UWord*    succs_words;
3708   //laog__sanity_check();
3709
3710   /* If the destination set is empty, we can never get there from
3711      'src' :-), so don't bother to try */
3712   if (HG_(isEmptyWS)( univ_lsets, dsts ))
3713      return NULL;
3714
3715   ret     = NULL;
3716   stack   = VG_(newXA)( HG_(zalloc), "hg.lddft.1", HG_(free), sizeof(Lock*) );
3717   visited = VG_(newFM)( HG_(zalloc), "hg.lddft.2", HG_(free), NULL/*unboxedcmp*/ );
3718
3719   (void) VG_(addToXA)( stack, &src );
3720
3721   while (True) {
3722
3723      ssz = VG_(sizeXA)( stack );
3724
3725      if (ssz == 0) { ret = NULL; break; }
3726
3727      here = *(Lock**) VG_(indexXA)( stack, ssz-1 );
3728      VG_(dropTailXA)( stack, 1 );
3729
3730      if (HG_(elemWS)( univ_lsets, dsts, (UWord)here )) { ret = here; break; }
3731
3732      if (VG_(lookupFM)( visited, NULL, NULL, (UWord)here ))
3733         continue;
3734
3735      VG_(addToFM)( visited, (UWord)here, 0 );
3736
3737      succs = laog__succs( here );
3738      HG_(getPayloadWS)( &succs_words, &succs_size, univ_laog, succs );
3739      for (i = 0; i < succs_size; i++)
3740         (void) VG_(addToXA)( stack, &succs_words[i] );
3741   }
3742
3743   VG_(deleteFM)( visited, NULL, NULL );
3744   VG_(deleteXA)( stack );
3745   return ret;
3746}
3747
3748
3749/* Thread 'thr' is acquiring 'lk'.  Check for inconsistent ordering
3750   between 'lk' and the locks already held by 'thr' and issue a
3751   complaint if so.  Also, update the ordering graph appropriately.
3752*/
3753__attribute__((noinline))
3754static void laog__pre_thread_acquires_lock (
3755               Thread* thr, /* NB: BEFORE lock is added */
3756               Lock*   lk
3757            )
3758{
3759   UWord*   ls_words;
3760   UWord    ls_size, i;
3761   Lock*    other;
3762
3763   /* It may be that 'thr' already holds 'lk' and is recursively
3764      relocking in.  In this case we just ignore the call. */
3765   /* NB: univ_lsets really is correct here */
3766   if (HG_(elemWS)( univ_lsets, thr->locksetA, (UWord)lk ))
3767      return;
3768
3769   /* First, the check.  Complain if there is any path in laog from lk
3770      to any of the locks already held by thr, since if any such path
3771      existed, it would mean that previously lk was acquired before
3772      (rather than after, as we are doing here) at least one of those
3773      locks.
3774   */
3775   other = laog__do_dfs_from_to(lk, thr->locksetA);
3776   if (other) {
3777      LAOGLinkExposition key, *found;
3778      /* So we managed to find a path lk --*--> other in the graph,
3779         which implies that 'lk' should have been acquired before
3780         'other' but is in fact being acquired afterwards.  We present
3781         the lk/other arguments to record_error_LockOrder in the order
3782         in which they should have been acquired. */
3783      /* Go look in the laog_exposition mapping, to find the allocation
3784         points for this edge, so we can show the user. */
3785      key.src_ga = lk->guestaddr;
3786      key.dst_ga = other->guestaddr;
3787      key.src_ec = NULL;
3788      key.dst_ec = NULL;
3789      found = NULL;
3790      if (VG_(lookupFM)( laog_exposition,
3791                         (UWord*)&found, NULL, (UWord)&key )) {
3792         tl_assert(found != &key);
3793         tl_assert(found->src_ga == key.src_ga);
3794         tl_assert(found->dst_ga == key.dst_ga);
3795         tl_assert(found->src_ec);
3796         tl_assert(found->dst_ec);
3797         HG_(record_error_LockOrder)(
3798            thr, lk->guestaddr, other->guestaddr,
3799                 found->src_ec, found->dst_ec, other->acquired_at );
3800      } else {
3801         /* Hmm.  This can't happen (can it?) */
3802         /* Yes, it can happen: see tests/tc14_laog_dinphils.
3803            Imagine we have 3 philosophers A B C, and the forks
3804            between them:
3805
3806                           C
3807
3808                       fCA   fBC
3809
3810                      A   fAB   B
3811
3812            Let's have the following actions:
3813                   A takes    fCA,fAB
3814                   A releases fCA,fAB
3815                   B takes    fAB,fBC
3816                   B releases fAB,fBC
3817                   C takes    fBC,fCA
3818                   C releases fBC,fCA
3819
3820            Helgrind will report a lock order error when C takes fCA.
3821            Effectively, we have a deadlock if the following
3822            sequence is done:
3823                A takes fCA
3824                B takes fAB
3825                C takes fBC
3826
3827            The error reported is:
3828              Observed (incorrect) order fBC followed by fCA
3829            but the stack traces that have established the required order
3830            are not given.
3831
3832            This is because there is no pair (fCA, fBC) in laog exposition :
3833            the laog_exposition records all pairs of locks between a new lock
3834            taken by a thread and all the already taken locks.
3835            So, there is no laog_exposition (fCA, fBC) as no thread ever
3836            first locked fCA followed by fBC.
3837
3838            In other words, when the deadlock cycle involves more than
3839            two locks, then helgrind does not report the sequence of
3840            operations that created the cycle.
3841
3842            However, we can report the current stack trace (where
3843            lk is being taken), and the stack trace where other was acquired:
3844            Effectively, the variable 'other' contains a lock currently
3845            held by this thread, with its 'acquired_at'. */
3846
3847         HG_(record_error_LockOrder)(
3848            thr, lk->guestaddr, other->guestaddr,
3849                 NULL, NULL, other->acquired_at );
3850      }
3851   }
3852
3853   /* Second, add to laog the pairs
3854        (old, lk)  |  old <- locks already held by thr
3855      Since both old and lk are currently held by thr, their acquired_at
3856      fields must be non-NULL.
3857   */
3858   tl_assert(lk->acquired_at);
3859   HG_(getPayloadWS)( &ls_words, &ls_size, univ_lsets, thr->locksetA );
3860   for (i = 0; i < ls_size; i++) {
3861      Lock* old = (Lock*)ls_words[i];
3862      tl_assert(old->acquired_at);
3863      laog__add_edge( old, lk );
3864   }
3865
3866   /* Why "except_Locks" ?  We're here because a lock is being
3867      acquired by a thread, and we're in an inconsistent state here.
3868      See the call points in evhH__post_thread_{r,w}_acquires_lock.
3869      When called in this inconsistent state, locks__sanity_check duly
3870      barfs. */
3871   if (HG_(clo_sanity_flags) & SCE_LAOG)
3872      all_except_Locks__sanity_check("laog__pre_thread_acquires_lock-post");
3873}
3874
3875/* Allocates a duplicate of words. Caller must HG_(free) the result. */
3876static UWord* UWordV_dup(UWord* words, Word words_size)
3877{
3878   UInt i;
3879
3880   if (words_size == 0)
3881      return NULL;
3882
3883   UWord *dup = HG_(zalloc) ("hg.dup.1", (SizeT) words_size * sizeof(UWord));
3884
3885   for (i = 0; i < words_size; i++)
3886      dup[i] = words[i];
3887
3888   return dup;
3889}
3890
3891/* Delete from 'laog' any pair mentioning a lock in locksToDelete */
3892
3893__attribute__((noinline))
3894static void laog__handle_one_lock_deletion ( Lock* lk )
3895{
3896   WordSetID preds, succs;
3897   UWord preds_size, succs_size, i, j;
3898   UWord *preds_words, *succs_words;
3899
3900   preds = laog__preds( lk );
3901   succs = laog__succs( lk );
3902
3903   // We need to duplicate the payload, as these can be garbage collected
3904   // during the del/add operations below.
3905   HG_(getPayloadWS)( &preds_words, &preds_size, univ_laog, preds );
3906   preds_words = UWordV_dup(preds_words, preds_size);
3907
3908   HG_(getPayloadWS)( &succs_words, &succs_size, univ_laog, succs );
3909   succs_words = UWordV_dup(succs_words, succs_size);
3910
3911   for (i = 0; i < preds_size; i++)
3912      laog__del_edge( (Lock*)preds_words[i], lk );
3913
3914   for (j = 0; j < succs_size; j++)
3915      laog__del_edge( lk, (Lock*)succs_words[j] );
3916
3917   for (i = 0; i < preds_size; i++) {
3918      for (j = 0; j < succs_size; j++) {
3919         if (preds_words[i] != succs_words[j]) {
3920            /* This can pass unlocked locks to laog__add_edge, since
3921               we're deleting stuff.  So their acquired_at fields may
3922               be NULL. */
3923            laog__add_edge( (Lock*)preds_words[i], (Lock*)succs_words[j] );
3924         }
3925      }
3926   }
3927
3928   if (preds_words)
3929      HG_(free) (preds_words);
3930   if (succs_words)
3931      HG_(free) (succs_words);
3932
3933   // Remove lk information from laog links FM
3934   {
3935      LAOGLinks *links;
3936      Lock* linked_lk;
3937
3938      if (VG_(delFromFM) (laog,
3939                          (UWord*)&linked_lk, (UWord*)&links, (UWord)lk)) {
3940         tl_assert (linked_lk == lk);
3941         HG_(free) (links);
3942      }
3943   }
3944   /* FIXME ??? What about removing lock lk data from EXPOSITION ??? */
3945}
3946
3947//__attribute__((noinline))
3948//static void laog__handle_lock_deletions (
3949//               WordSetID /* in univ_laog */ locksToDelete
3950//            )
3951//{
3952//   Word   i, ws_size;
3953//   UWord* ws_words;
3954//
3955//
3956//   HG_(getPayloadWS)( &ws_words, &ws_size, univ_lsets, locksToDelete );
3957//   UWordV_dup call needed here ...
3958//   for (i = 0; i < ws_size; i++)
3959//      laog__handle_one_lock_deletion( (Lock*)ws_words[i] );
3960//
3961//   if (HG_(clo_sanity_flags) & SCE_LAOG)
3962//      all__sanity_check("laog__handle_lock_deletions-post");
3963//}
3964
3965
3966/*--------------------------------------------------------------*/
3967/*--- Malloc/free replacements                               ---*/
3968/*--------------------------------------------------------------*/
3969
3970typedef
3971   struct {
3972      void*       next;    /* required by m_hashtable */
3973      Addr        payload; /* ptr to actual block    */
3974      SizeT       szB;     /* size requested         */
3975      ExeContext* where;   /* where it was allocated */
3976      Thread*     thr;     /* allocating thread      */
3977   }
3978   MallocMeta;
3979
3980/* A hash table of MallocMetas, used to track malloc'd blocks
3981   (obviously). */
3982static VgHashTable hg_mallocmeta_table = NULL;
3983
3984/* MallocMeta are small elements. We use a pool to avoid
3985   the overhead of malloc for each MallocMeta. */
3986static PoolAlloc *MallocMeta_poolalloc = NULL;
3987
3988static MallocMeta* new_MallocMeta ( void ) {
3989   MallocMeta* md = VG_(allocEltPA) (MallocMeta_poolalloc);
3990   VG_(memset)(md, 0, sizeof(MallocMeta));
3991   return md;
3992}
3993static void delete_MallocMeta ( MallocMeta* md ) {
3994   VG_(freeEltPA)(MallocMeta_poolalloc, md);
3995}
3996
3997
3998/* Allocate a client block and set up the metadata for it. */
3999
4000static
4001void* handle_alloc ( ThreadId tid,
4002                     SizeT szB, SizeT alignB, Bool is_zeroed )
4003{
4004   Addr        p;
4005   MallocMeta* md;
4006
4007   tl_assert( ((SSizeT)szB) >= 0 );
4008   p = (Addr)VG_(cli_malloc)(alignB, szB);
4009   if (!p) {
4010      return NULL;
4011   }
4012   if (is_zeroed)
4013      VG_(memset)((void*)p, 0, szB);
4014
4015   /* Note that map_threads_lookup must succeed (cannot assert), since
4016      memory can only be allocated by currently alive threads, hence
4017      they must have an entry in map_threads. */
4018   md = new_MallocMeta();
4019   md->payload = p;
4020   md->szB     = szB;
4021   md->where   = VG_(record_ExeContext)( tid, 0 );
4022   md->thr     = map_threads_lookup( tid );
4023
4024   VG_(HT_add_node)( hg_mallocmeta_table, (VgHashNode*)md );
4025
4026   /* Tell the lower level memory wranglers. */
4027   evh__new_mem_heap( p, szB, is_zeroed );
4028
4029   return (void*)p;
4030}
4031
4032/* Re the checks for less-than-zero (also in hg_cli__realloc below):
4033   Cast to a signed type to catch any unexpectedly negative args.
4034   We're assuming here that the size asked for is not greater than
4035   2^31 bytes (for 32-bit platforms) or 2^63 bytes (for 64-bit
4036   platforms). */
4037static void* hg_cli__malloc ( ThreadId tid, SizeT n ) {
4038   if (((SSizeT)n) < 0) return NULL;
4039   return handle_alloc ( tid, n, VG_(clo_alignment),
4040                         /*is_zeroed*/False );
4041}
4042static void* hg_cli____builtin_new ( ThreadId tid, SizeT n ) {
4043   if (((SSizeT)n) < 0) return NULL;
4044   return handle_alloc ( tid, n, VG_(clo_alignment),
4045                         /*is_zeroed*/False );
4046}
4047static void* hg_cli____builtin_vec_new ( ThreadId tid, SizeT n ) {
4048   if (((SSizeT)n) < 0) return NULL;
4049   return handle_alloc ( tid, n, VG_(clo_alignment),
4050                         /*is_zeroed*/False );
4051}
4052static void* hg_cli__memalign ( ThreadId tid, SizeT align, SizeT n ) {
4053   if (((SSizeT)n) < 0) return NULL;
4054   return handle_alloc ( tid, n, align,
4055                         /*is_zeroed*/False );
4056}
4057static void* hg_cli__calloc ( ThreadId tid, SizeT nmemb, SizeT size1 ) {
4058   if ( ((SSizeT)nmemb) < 0 || ((SSizeT)size1) < 0 ) return NULL;
4059   return handle_alloc ( tid, nmemb*size1, VG_(clo_alignment),
4060                         /*is_zeroed*/True );
4061}
4062
4063
4064/* Free a client block, including getting rid of the relevant
4065   metadata. */
4066
4067static void handle_free ( ThreadId tid, void* p )
4068{
4069   MallocMeta *md, *old_md;
4070   SizeT      szB;
4071
4072   /* First see if we can find the metadata for 'p'. */
4073   md = (MallocMeta*) VG_(HT_lookup)( hg_mallocmeta_table, (UWord)p );
4074   if (!md)
4075      return; /* apparently freeing a bogus address.  Oh well. */
4076
4077   tl_assert(md->payload == (Addr)p);
4078   szB = md->szB;
4079
4080   /* Nuke the metadata block */
4081   old_md = (MallocMeta*)
4082            VG_(HT_remove)( hg_mallocmeta_table, (UWord)p );
4083   tl_assert(old_md); /* it must be present - we just found it */
4084   tl_assert(old_md == md);
4085   tl_assert(old_md->payload == (Addr)p);
4086
4087   VG_(cli_free)((void*)old_md->payload);
4088   delete_MallocMeta(old_md);
4089
4090   /* Tell the lower level memory wranglers. */
4091   evh__die_mem_heap( (Addr)p, szB );
4092}
4093
4094static void hg_cli__free ( ThreadId tid, void* p ) {
4095   handle_free(tid, p);
4096}
4097static void hg_cli____builtin_delete ( ThreadId tid, void* p ) {
4098   handle_free(tid, p);
4099}
4100static void hg_cli____builtin_vec_delete ( ThreadId tid, void* p ) {
4101   handle_free(tid, p);
4102}
4103
4104
4105static void* hg_cli__realloc ( ThreadId tid, void* payloadV, SizeT new_size )
4106{
4107   MallocMeta *md, *md_new, *md_tmp;
4108   SizeT      i;
4109
4110   Addr payload = (Addr)payloadV;
4111
4112   if (((SSizeT)new_size) < 0) return NULL;
4113
4114   md = (MallocMeta*) VG_(HT_lookup)( hg_mallocmeta_table, (UWord)payload );
4115   if (!md)
4116      return NULL; /* apparently realloc-ing a bogus address.  Oh well. */
4117
4118   tl_assert(md->payload == payload);
4119
4120   if (md->szB == new_size) {
4121      /* size unchanged */
4122      md->where = VG_(record_ExeContext)(tid, 0);
4123      return payloadV;
4124   }
4125
4126   if (md->szB > new_size) {
4127      /* new size is smaller */
4128      md->szB   = new_size;
4129      md->where = VG_(record_ExeContext)(tid, 0);
4130      evh__die_mem_heap( md->payload + new_size, md->szB - new_size );
4131      return payloadV;
4132   }
4133
4134   /* else */ {
4135      /* new size is bigger */
4136      Addr p_new = (Addr)VG_(cli_malloc)(VG_(clo_alignment), new_size);
4137
4138      /* First half kept and copied, second half new */
4139      // FIXME: shouldn't we use a copier which implements the
4140      // memory state machine?
4141      evh__copy_mem( payload, p_new, md->szB );
4142      evh__new_mem_heap ( p_new + md->szB, new_size - md->szB,
4143                          /*inited*/False );
4144      /* FIXME: can anything funny happen here?  specifically, if the
4145         old range contained a lock, then die_mem_heap will complain.
4146         Is that the correct behaviour?  Not sure. */
4147      evh__die_mem_heap( payload, md->szB );
4148
4149      /* Copy from old to new */
4150      for (i = 0; i < md->szB; i++)
4151         ((UChar*)p_new)[i] = ((UChar*)payload)[i];
4152
4153      /* Because the metadata hash table is index by payload address,
4154         we have to get rid of the old hash table entry and make a new
4155         one.  We can't just modify the existing metadata in place,
4156         because then it would (almost certainly) be in the wrong hash
4157         chain. */
4158      md_new = new_MallocMeta();
4159      *md_new = *md;
4160
4161      md_tmp = VG_(HT_remove)( hg_mallocmeta_table, payload );
4162      tl_assert(md_tmp);
4163      tl_assert(md_tmp == md);
4164
4165      VG_(cli_free)((void*)md->payload);
4166      delete_MallocMeta(md);
4167
4168      /* Update fields */
4169      md_new->where   = VG_(record_ExeContext)( tid, 0 );
4170      md_new->szB     = new_size;
4171      md_new->payload = p_new;
4172      md_new->thr     = map_threads_lookup( tid );
4173
4174      /* and add */
4175      VG_(HT_add_node)( hg_mallocmeta_table, (VgHashNode*)md_new );
4176
4177      return (void*)p_new;
4178   }
4179}
4180
4181static SizeT hg_cli_malloc_usable_size ( ThreadId tid, void* p )
4182{
4183   MallocMeta *md = VG_(HT_lookup)( hg_mallocmeta_table, (UWord)p );
4184
4185   // There may be slop, but pretend there isn't because only the asked-for
4186   // area will have been shadowed properly.
4187   return ( md ? md->szB : 0 );
4188}
4189
4190
4191/* For error creation: map 'data_addr' to a malloc'd chunk, if any.
4192   Slow linear search.  With a bit of hash table help if 'data_addr'
4193   is either the start of a block or up to 15 word-sized steps along
4194   from the start of a block. */
4195
4196static inline Bool addr_is_in_MM_Chunk( MallocMeta* mm, Addr a )
4197{
4198   /* Accept 'a' as within 'mm' if 'mm's size is zero and 'a' points
4199      right at it. */
4200  if (UNLIKELY(mm->szB == 0 && a == mm->payload))
4201     return True;
4202  /* else normal interval rules apply */
4203  if (LIKELY(a < mm->payload)) return False;
4204  if (LIKELY(a >= mm->payload + mm->szB)) return False;
4205  return True;
4206}
4207
4208Bool HG_(mm_find_containing_block)( /*OUT*/ExeContext** where,
4209                                    /*OUT*/Addr*        payload,
4210                                    /*OUT*/SizeT*       szB,
4211                                    Addr                data_addr )
4212{
4213   MallocMeta* mm;
4214   Int i;
4215   const Int n_fast_check_words = 16;
4216
4217   /* First, do a few fast searches on the basis that data_addr might
4218      be exactly the start of a block or up to 15 words inside.  This
4219      can happen commonly via the creq
4220      _VG_USERREQ__HG_CLEAN_MEMORY_HEAPBLOCK. */
4221   for (i = 0; i < n_fast_check_words; i++) {
4222      mm = VG_(HT_lookup)( hg_mallocmeta_table,
4223                           data_addr - (UWord)(UInt)i * sizeof(UWord) );
4224      if (UNLIKELY(mm && addr_is_in_MM_Chunk(mm, data_addr)))
4225         goto found;
4226   }
4227
4228   /* Well, this totally sucks.  But without using an interval tree or
4229      some such, it's hard to see how to do better.  We have to check
4230      every block in the entire table. */
4231   VG_(HT_ResetIter)(hg_mallocmeta_table);
4232   while ( (mm = VG_(HT_Next)(hg_mallocmeta_table)) ) {
4233      if (UNLIKELY(addr_is_in_MM_Chunk(mm, data_addr)))
4234         goto found;
4235   }
4236
4237   /* Not found.  Bah. */
4238   return False;
4239   /*NOTREACHED*/
4240
4241  found:
4242   tl_assert(mm);
4243   tl_assert(addr_is_in_MM_Chunk(mm, data_addr));
4244   if (where)   *where   = mm->where;
4245   if (payload) *payload = mm->payload;
4246   if (szB)     *szB     = mm->szB;
4247   return True;
4248}
4249
4250
4251/*--------------------------------------------------------------*/
4252/*--- Instrumentation                                        ---*/
4253/*--------------------------------------------------------------*/
4254
4255#define unop(_op, _arg1)         IRExpr_Unop((_op),(_arg1))
4256#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2))
4257#define mkexpr(_tmp)             IRExpr_RdTmp((_tmp))
4258#define mkU32(_n)                IRExpr_Const(IRConst_U32(_n))
4259#define mkU64(_n)                IRExpr_Const(IRConst_U64(_n))
4260#define assign(_t, _e)           IRStmt_WrTmp((_t), (_e))
4261
4262/* This takes and returns atoms, of course.  Not full IRExprs. */
4263static IRExpr* mk_And1 ( IRSB* sbOut, IRExpr* arg1, IRExpr* arg2 )
4264{
4265   tl_assert(arg1 && arg2);
4266   tl_assert(isIRAtom(arg1));
4267   tl_assert(isIRAtom(arg2));
4268   /* Generate 32to1(And32(1Uto32(arg1), 1Uto32(arg2))).  Appalling
4269      code, I know. */
4270   IRTemp wide1 = newIRTemp(sbOut->tyenv, Ity_I32);
4271   IRTemp wide2 = newIRTemp(sbOut->tyenv, Ity_I32);
4272   IRTemp anded = newIRTemp(sbOut->tyenv, Ity_I32);
4273   IRTemp res   = newIRTemp(sbOut->tyenv, Ity_I1);
4274   addStmtToIRSB(sbOut, assign(wide1, unop(Iop_1Uto32, arg1)));
4275   addStmtToIRSB(sbOut, assign(wide2, unop(Iop_1Uto32, arg2)));
4276   addStmtToIRSB(sbOut, assign(anded, binop(Iop_And32, mkexpr(wide1),
4277                                                       mkexpr(wide2))));
4278   addStmtToIRSB(sbOut, assign(res, unop(Iop_32to1, mkexpr(anded))));
4279   return mkexpr(res);
4280}
4281
4282static void instrument_mem_access ( IRSB*   sbOut,
4283                                    IRExpr* addr,
4284                                    Int     szB,
4285                                    Bool    isStore,
4286                                    Int     hWordTy_szB,
4287                                    Int     goff_sp,
4288                                    IRExpr* guard ) /* NULL => True */
4289{
4290   IRType   tyAddr   = Ity_INVALID;
4291   const HChar* hName    = NULL;
4292   void*    hAddr    = NULL;
4293   Int      regparms = 0;
4294   IRExpr** argv     = NULL;
4295   IRDirty* di       = NULL;
4296
4297   // THRESH is the size of the window above SP (well,
4298   // mostly above) that we assume implies a stack reference.
4299   const Int THRESH = 4096 * 4; // somewhat arbitrary
4300   const Int rz_szB = VG_STACK_REDZONE_SZB;
4301
4302   tl_assert(isIRAtom(addr));
4303   tl_assert(hWordTy_szB == 4 || hWordTy_szB == 8);
4304
4305   tyAddr = typeOfIRExpr( sbOut->tyenv, addr );
4306   tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);
4307
4308   /* So the effective address is in 'addr' now. */
4309   regparms = 1; // unless stated otherwise
4310   if (isStore) {
4311      switch (szB) {
4312         case 1:
4313            hName = "evh__mem_help_cwrite_1";
4314            hAddr = &evh__mem_help_cwrite_1;
4315            argv = mkIRExprVec_1( addr );
4316            break;
4317         case 2:
4318            hName = "evh__mem_help_cwrite_2";
4319            hAddr = &evh__mem_help_cwrite_2;
4320            argv = mkIRExprVec_1( addr );
4321            break;
4322         case 4:
4323            hName = "evh__mem_help_cwrite_4";
4324            hAddr = &evh__mem_help_cwrite_4;
4325            argv = mkIRExprVec_1( addr );
4326            break;
4327         case 8:
4328            hName = "evh__mem_help_cwrite_8";
4329            hAddr = &evh__mem_help_cwrite_8;
4330            argv = mkIRExprVec_1( addr );
4331            break;
4332         default:
4333            tl_assert(szB > 8 && szB <= 512); /* stay sane */
4334            regparms = 2;
4335            hName = "evh__mem_help_cwrite_N";
4336            hAddr = &evh__mem_help_cwrite_N;
4337            argv = mkIRExprVec_2( addr, mkIRExpr_HWord( szB ));
4338            break;
4339      }
4340   } else {
4341      switch (szB) {
4342         case 1:
4343            hName = "evh__mem_help_cread_1";
4344            hAddr = &evh__mem_help_cread_1;
4345            argv = mkIRExprVec_1( addr );
4346            break;
4347         case 2:
4348            hName = "evh__mem_help_cread_2";
4349            hAddr = &evh__mem_help_cread_2;
4350            argv = mkIRExprVec_1( addr );
4351            break;
4352         case 4:
4353            hName = "evh__mem_help_cread_4";
4354            hAddr = &evh__mem_help_cread_4;
4355            argv = mkIRExprVec_1( addr );
4356            break;
4357         case 8:
4358            hName = "evh__mem_help_cread_8";
4359            hAddr = &evh__mem_help_cread_8;
4360            argv = mkIRExprVec_1( addr );
4361            break;
4362         default:
4363            tl_assert(szB > 8 && szB <= 512); /* stay sane */
4364            regparms = 2;
4365            hName = "evh__mem_help_cread_N";
4366            hAddr = &evh__mem_help_cread_N;
4367            argv = mkIRExprVec_2( addr, mkIRExpr_HWord( szB ));
4368            break;
4369      }
4370   }
4371
4372   /* Create the helper. */
4373   tl_assert(hName);
4374   tl_assert(hAddr);
4375   tl_assert(argv);
4376   di = unsafeIRDirty_0_N( regparms,
4377                           hName, VG_(fnptr_to_fnentry)( hAddr ),
4378                           argv );
4379
4380   if (! HG_(clo_check_stack_refs)) {
4381      /* We're ignoring memory references which are (obviously) to the
4382         stack.  In fact just skip stack refs that are within 4 pages
4383         of SP (SP - the redzone, really), as that's simple, easy, and
4384         filters out most stack references. */
4385      /* Generate the guard condition: "(addr - (SP - RZ)) >u N", for
4386         some arbitrary N.  If that is true then addr is outside the
4387         range (SP - RZ .. SP + N - RZ).  If N is smallish (a few
4388         pages) then we can say addr is within a few pages of SP and
4389         so can't possibly be a heap access, and so can be skipped.
4390
4391         Note that the condition simplifies to
4392            (addr - SP + RZ) >u N
4393         which generates better code in x86/amd64 backends, but it does
4394         not unfortunately simplify to
4395            (addr - SP) >u (N - RZ)
4396         (would be beneficial because N - RZ is a constant) because
4397         wraparound arithmetic messes up the comparison.  eg.
4398         20 >u 10 == True,
4399         but (20 - 15) >u (10 - 15) == 5 >u (MAXINT-5) == False.
4400      */
4401      IRTemp sp = newIRTemp(sbOut->tyenv, tyAddr);
4402      addStmtToIRSB( sbOut, assign(sp, IRExpr_Get(goff_sp, tyAddr)));
4403
4404      /* "addr - SP" */
4405      IRTemp addr_minus_sp = newIRTemp(sbOut->tyenv, tyAddr);
4406      addStmtToIRSB(
4407         sbOut,
4408         assign(addr_minus_sp,
4409                tyAddr == Ity_I32
4410                   ? binop(Iop_Sub32, addr, mkexpr(sp))
4411                   : binop(Iop_Sub64, addr, mkexpr(sp)))
4412      );
4413
4414      /* "addr - SP + RZ" */
4415      IRTemp diff = newIRTemp(sbOut->tyenv, tyAddr);
4416      addStmtToIRSB(
4417         sbOut,
4418         assign(diff,
4419                tyAddr == Ity_I32
4420                   ? binop(Iop_Add32, mkexpr(addr_minus_sp), mkU32(rz_szB))
4421                   : binop(Iop_Add64, mkexpr(addr_minus_sp), mkU64(rz_szB)))
4422      );
4423
4424      /* guardA == "guard on the address" */
4425      IRTemp guardA = newIRTemp(sbOut->tyenv, Ity_I1);
4426      addStmtToIRSB(
4427         sbOut,
4428         assign(guardA,
4429                tyAddr == Ity_I32
4430                   ? binop(Iop_CmpLT32U, mkU32(THRESH), mkexpr(diff))
4431                   : binop(Iop_CmpLT64U, mkU64(THRESH), mkexpr(diff)))
4432      );
4433      di->guard = mkexpr(guardA);
4434   }
4435
4436   /* If there's a guard on the access itself (as supplied by the
4437      caller of this routine), we need to AND that in to any guard we
4438      might already have. */
4439   if (guard) {
4440      di->guard = mk_And1(sbOut, di->guard, guard);
4441   }
4442
4443   /* Add the helper. */
4444   addStmtToIRSB( sbOut, IRStmt_Dirty(di) );
4445}
4446
4447
4448/* Figure out if GA is a guest code address in the dynamic linker, and
4449   if so return True.  Otherwise (and in case of any doubt) return
4450   False.  (sidedly safe w/ False as the safe value) */
4451static Bool is_in_dynamic_linker_shared_object( Addr64 ga )
4452{
4453   DebugInfo* dinfo;
4454   const HChar* soname;
4455   if (0) return False;
4456
4457   dinfo = VG_(find_DebugInfo)( (Addr)ga );
4458   if (!dinfo) return False;
4459
4460   soname = VG_(DebugInfo_get_soname)(dinfo);
4461   tl_assert(soname);
4462   if (0) VG_(printf)("%s\n", soname);
4463
4464#  if defined(VGO_linux)
4465   if (VG_STREQ(soname, VG_U_LD_LINUX_SO_3))        return True;
4466   if (VG_STREQ(soname, VG_U_LD_LINUX_SO_2))        return True;
4467   if (VG_STREQ(soname, VG_U_LD_LINUX_X86_64_SO_2)) return True;
4468   if (VG_STREQ(soname, VG_U_LD64_SO_1))            return True;
4469   if (VG_STREQ(soname, VG_U_LD_SO_1))              return True;
4470#  elif defined(VGO_darwin)
4471   if (VG_STREQ(soname, VG_U_DYLD)) return True;
4472#  else
4473#    error "Unsupported OS"
4474#  endif
4475   return False;
4476}
4477
4478static
4479IRSB* hg_instrument ( VgCallbackClosure* closure,
4480                      IRSB* bbIn,
4481                      VexGuestLayout* layout,
4482                      VexGuestExtents* vge,
4483                      VexArchInfo* archinfo_host,
4484                      IRType gWordTy, IRType hWordTy )
4485{
4486   Int     i;
4487   IRSB*   bbOut;
4488   Addr64  cia; /* address of current insn */
4489   IRStmt* st;
4490   Bool    inLDSO = False;
4491   Addr64  inLDSOmask4K = 1; /* mismatches on first check */
4492
4493   const Int goff_sp = layout->offset_SP;
4494
4495   if (gWordTy != hWordTy) {
4496      /* We don't currently support this case. */
4497      VG_(tool_panic)("host/guest word size mismatch");
4498   }
4499
4500   if (VKI_PAGE_SIZE < 4096 || VG_(log2)(VKI_PAGE_SIZE) == -1) {
4501      VG_(tool_panic)("implausible or too-small VKI_PAGE_SIZE");
4502   }
4503
4504   /* Set up BB */
4505   bbOut           = emptyIRSB();
4506   bbOut->tyenv    = deepCopyIRTypeEnv(bbIn->tyenv);
4507   bbOut->next     = deepCopyIRExpr(bbIn->next);
4508   bbOut->jumpkind = bbIn->jumpkind;
4509   bbOut->offsIP   = bbIn->offsIP;
4510
4511   // Copy verbatim any IR preamble preceding the first IMark
4512   i = 0;
4513   while (i < bbIn->stmts_used && bbIn->stmts[i]->tag != Ist_IMark) {
4514      addStmtToIRSB( bbOut, bbIn->stmts[i] );
4515      i++;
4516   }
4517
4518   // Get the first statement, and initial cia from it
4519   tl_assert(bbIn->stmts_used > 0);
4520   tl_assert(i < bbIn->stmts_used);
4521   st = bbIn->stmts[i];
4522   tl_assert(Ist_IMark == st->tag);
4523   cia = st->Ist.IMark.addr;
4524   st = NULL;
4525
4526   for (/*use current i*/; i < bbIn->stmts_used; i++) {
4527      st = bbIn->stmts[i];
4528      tl_assert(st);
4529      tl_assert(isFlatIRStmt(st));
4530      switch (st->tag) {
4531         case Ist_NoOp:
4532         case Ist_AbiHint:
4533         case Ist_Put:
4534         case Ist_PutI:
4535         case Ist_Exit:
4536            /* None of these can contain any memory references. */
4537            break;
4538
4539         case Ist_IMark:
4540            /* no mem refs, but note the insn address. */
4541            cia = st->Ist.IMark.addr;
4542            /* Don't instrument the dynamic linker.  It generates a
4543               lot of races which we just expensively suppress, so
4544               it's pointless.
4545
4546               Avoid flooding is_in_dynamic_linker_shared_object with
4547               requests by only checking at transitions between 4K
4548               pages. */
4549            if ((cia & ~(Addr64)0xFFF) != inLDSOmask4K) {
4550               if (0) VG_(printf)("NEW %#lx\n", (Addr)cia);
4551               inLDSOmask4K = cia & ~(Addr64)0xFFF;
4552               inLDSO = is_in_dynamic_linker_shared_object(cia);
4553            } else {
4554               if (0) VG_(printf)("old %#lx\n", (Addr)cia);
4555            }
4556            break;
4557
4558         case Ist_MBE:
4559            switch (st->Ist.MBE.event) {
4560               case Imbe_Fence:
4561                  break; /* not interesting */
4562               default:
4563                  goto unhandled;
4564            }
4565            break;
4566
4567         case Ist_CAS: {
4568            /* Atomic read-modify-write cycle.  Just pretend it's a
4569               read. */
4570            IRCAS* cas    = st->Ist.CAS.details;
4571            Bool   isDCAS = cas->oldHi != IRTemp_INVALID;
4572            if (isDCAS) {
4573               tl_assert(cas->expdHi);
4574               tl_assert(cas->dataHi);
4575            } else {
4576               tl_assert(!cas->expdHi);
4577               tl_assert(!cas->dataHi);
4578            }
4579            /* Just be boring about it. */
4580            if (!inLDSO) {
4581               instrument_mem_access(
4582                  bbOut,
4583                  cas->addr,
4584                  (isDCAS ? 2 : 1)
4585                     * sizeofIRType(typeOfIRExpr(bbIn->tyenv, cas->dataLo)),
4586                  False/*!isStore*/,
4587                  sizeofIRType(hWordTy), goff_sp,
4588                  NULL/*no-guard*/
4589               );
4590            }
4591            break;
4592         }
4593
4594         case Ist_LLSC: {
4595            /* We pretend store-conditionals don't exist, viz, ignore
4596               them.  Whereas load-linked's are treated the same as
4597               normal loads. */
4598            IRType dataTy;
4599            if (st->Ist.LLSC.storedata == NULL) {
4600               /* LL */
4601               dataTy = typeOfIRTemp(bbIn->tyenv, st->Ist.LLSC.result);
4602               if (!inLDSO) {
4603                  instrument_mem_access(
4604                     bbOut,
4605                     st->Ist.LLSC.addr,
4606                     sizeofIRType(dataTy),
4607                     False/*!isStore*/,
4608                     sizeofIRType(hWordTy), goff_sp,
4609                     NULL/*no-guard*/
4610                  );
4611               }
4612            } else {
4613               /* SC */
4614               /*ignore */
4615            }
4616            break;
4617         }
4618
4619         case Ist_Store:
4620            if (!inLDSO) {
4621               instrument_mem_access(
4622                  bbOut,
4623                  st->Ist.Store.addr,
4624                  sizeofIRType(typeOfIRExpr(bbIn->tyenv, st->Ist.Store.data)),
4625                  True/*isStore*/,
4626                  sizeofIRType(hWordTy), goff_sp,
4627                  NULL/*no-guard*/
4628               );
4629            }
4630            break;
4631
4632         case Ist_StoreG: {
4633            IRStoreG* sg   = st->Ist.StoreG.details;
4634            IRExpr*   data = sg->data;
4635            IRExpr*   addr = sg->addr;
4636            IRType    type = typeOfIRExpr(bbIn->tyenv, data);
4637            tl_assert(type != Ity_INVALID);
4638            instrument_mem_access( bbOut, addr, sizeofIRType(type),
4639                                   True/*isStore*/,
4640                                   sizeofIRType(hWordTy),
4641                                   goff_sp, sg->guard );
4642            break;
4643         }
4644
4645         case Ist_LoadG: {
4646            IRLoadG* lg       = st->Ist.LoadG.details;
4647            IRType   type     = Ity_INVALID; /* loaded type */
4648            IRType   typeWide = Ity_INVALID; /* after implicit widening */
4649            IRExpr*  addr     = lg->addr;
4650            typeOfIRLoadGOp(lg->cvt, &typeWide, &type);
4651            tl_assert(type != Ity_INVALID);
4652            instrument_mem_access( bbOut, addr, sizeofIRType(type),
4653                                   False/*!isStore*/,
4654                                   sizeofIRType(hWordTy),
4655                                   goff_sp, lg->guard );
4656            break;
4657         }
4658
4659         case Ist_WrTmp: {
4660            IRExpr* data = st->Ist.WrTmp.data;
4661            if (data->tag == Iex_Load) {
4662               if (!inLDSO) {
4663                  instrument_mem_access(
4664                     bbOut,
4665                     data->Iex.Load.addr,
4666                     sizeofIRType(data->Iex.Load.ty),
4667                     False/*!isStore*/,
4668                     sizeofIRType(hWordTy), goff_sp,
4669                     NULL/*no-guard*/
4670                  );
4671               }
4672            }
4673            break;
4674         }
4675
4676         case Ist_Dirty: {
4677            Int      dataSize;
4678            IRDirty* d = st->Ist.Dirty.details;
4679            if (d->mFx != Ifx_None) {
4680               /* This dirty helper accesses memory.  Collect the
4681                  details. */
4682               tl_assert(d->mAddr != NULL);
4683               tl_assert(d->mSize != 0);
4684               dataSize = d->mSize;
4685               if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify) {
4686                  if (!inLDSO) {
4687                     instrument_mem_access(
4688                        bbOut, d->mAddr, dataSize, False/*!isStore*/,
4689                        sizeofIRType(hWordTy), goff_sp, NULL/*no-guard*/
4690                     );
4691                  }
4692               }
4693               if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify) {
4694                  if (!inLDSO) {
4695                     instrument_mem_access(
4696                        bbOut, d->mAddr, dataSize, True/*isStore*/,
4697                        sizeofIRType(hWordTy), goff_sp, NULL/*no-guard*/
4698                     );
4699                  }
4700               }
4701            } else {
4702               tl_assert(d->mAddr == NULL);
4703               tl_assert(d->mSize == 0);
4704            }
4705            break;
4706         }
4707
4708         default:
4709         unhandled:
4710            ppIRStmt(st);
4711            tl_assert(0);
4712
4713      } /* switch (st->tag) */
4714
4715      addStmtToIRSB( bbOut, st );
4716   } /* iterate over bbIn->stmts */
4717
4718   return bbOut;
4719}
4720
4721#undef binop
4722#undef mkexpr
4723#undef mkU32
4724#undef mkU64
4725#undef assign
4726
4727
4728/*----------------------------------------------------------------*/
4729/*--- Client requests                                          ---*/
4730/*----------------------------------------------------------------*/
4731
4732/* Sheesh.  Yet another goddam finite map. */
4733static WordFM* map_pthread_t_to_Thread = NULL; /* pthread_t -> Thread* */
4734
4735static void map_pthread_t_to_Thread_INIT ( void ) {
4736   if (UNLIKELY(map_pthread_t_to_Thread == NULL)) {
4737      map_pthread_t_to_Thread = VG_(newFM)( HG_(zalloc), "hg.mpttT.1",
4738                                            HG_(free), NULL );
4739      tl_assert(map_pthread_t_to_Thread != NULL);
4740   }
4741}
4742
4743static void print_monitor_help ( void )
4744{
4745   VG_(gdb_printf)
4746      (
4747"\n"
4748"helgrind monitor commands:\n"
4749"  info locks              : show list of locks and their status\n"
4750"\n");
4751}
4752
4753/* return True if request recognised, False otherwise */
4754static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
4755{
4756   HChar* wcmd;
4757   HChar s[VG_(strlen(req))]; /* copy for strtok_r */
4758   HChar *ssaveptr;
4759   Int   kwdid;
4760
4761   VG_(strcpy) (s, req);
4762
4763   wcmd = VG_(strtok_r) (s, " ", &ssaveptr);
4764   /* NB: if possible, avoid introducing a new command below which
4765      starts with the same first letter(s) as an already existing
4766      command. This ensures a shorter abbreviation for the user. */
4767   switch (VG_(keyword_id)
4768           ("help info",
4769            wcmd, kwd_report_duplicated_matches)) {
4770   case -2: /* multiple matches */
4771      return True;
4772   case -1: /* not found */
4773      return False;
4774   case  0: /* help */
4775      print_monitor_help();
4776      return True;
4777   case  1: /* info */
4778      wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
4779      switch (kwdid = VG_(keyword_id)
4780              ("locks",
4781               wcmd, kwd_report_all)) {
4782      case -2:
4783      case -1:
4784         break;
4785      case 0: // locks
4786         {
4787            Int i;
4788            Lock* lk;
4789            for (i = 0, lk = admin_locks;  lk;  i++, lk = lk->admin_next) {
4790               pp_Lock(0, lk,
4791                       True /* show_lock_addrdescr */,
4792                       False /* show_internal_data */);
4793            }
4794            if (i == 0)
4795               VG_(gdb_printf) ("no locks\n");
4796         }
4797         break;
4798      default:
4799         tl_assert(0);
4800      }
4801      return True;
4802   default:
4803      tl_assert(0);
4804      return False;
4805   }
4806}
4807
4808static
4809Bool hg_handle_client_request ( ThreadId tid, UWord* args, UWord* ret)
4810{
4811   if (!VG_IS_TOOL_USERREQ('H','G',args[0])
4812       && VG_USERREQ__GDB_MONITOR_COMMAND   != args[0])
4813      return False;
4814
4815   /* Anything that gets past the above check is one of ours, so we
4816      should be able to handle it. */
4817
4818   /* default, meaningless return value, unless otherwise set */
4819   *ret = 0;
4820
4821   switch (args[0]) {
4822
4823      /* --- --- User-visible client requests --- --- */
4824
4825      case VG_USERREQ__HG_CLEAN_MEMORY:
4826         if (0) VG_(printf)("VG_USERREQ__HG_CLEAN_MEMORY(%#lx,%ld)\n",
4827                            args[1], args[2]);
4828         /* Call die_mem to (expensively) tidy up properly, if there
4829            are any held locks etc in the area.  Calling evh__die_mem
4830            and then evh__new_mem is a bit inefficient; probably just
4831            the latter would do. */
4832         if (args[2] > 0) { /* length */
4833            evh__die_mem(args[1], args[2]);
4834            /* and then set it to New */
4835            evh__new_mem(args[1], args[2]);
4836         }
4837         break;
4838
4839      case _VG_USERREQ__HG_CLEAN_MEMORY_HEAPBLOCK: {
4840         Addr  payload = 0;
4841         SizeT pszB = 0;
4842         if (0) VG_(printf)("VG_USERREQ__HG_CLEAN_MEMORY_HEAPBLOCK(%#lx)\n",
4843                            args[1]);
4844         if (HG_(mm_find_containing_block)(NULL, &payload, &pszB, args[1])) {
4845            if (pszB > 0) {
4846               evh__die_mem(payload, pszB);
4847               evh__new_mem(payload, pszB);
4848            }
4849            *ret = pszB;
4850         } else {
4851            *ret = (UWord)-1;
4852         }
4853         break;
4854      }
4855
4856      case _VG_USERREQ__HG_ARANGE_MAKE_UNTRACKED:
4857         if (0) VG_(printf)("HG_ARANGE_MAKE_UNTRACKED(%#lx,%ld)\n",
4858                            args[1], args[2]);
4859         if (args[2] > 0) { /* length */
4860            evh__untrack_mem(args[1], args[2]);
4861         }
4862         break;
4863
4864      case _VG_USERREQ__HG_ARANGE_MAKE_TRACKED:
4865         if (0) VG_(printf)("HG_ARANGE_MAKE_TRACKED(%#lx,%ld)\n",
4866                            args[1], args[2]);
4867         if (args[2] > 0) { /* length */
4868            evh__new_mem(args[1], args[2]);
4869         }
4870         break;
4871
4872      /* --- --- Client requests for Helgrind's use only --- --- */
4873
4874      /* Some thread is telling us its pthread_t value.  Record the
4875         binding between that and the associated Thread*, so we can
4876         later find the Thread* again when notified of a join by the
4877         thread. */
4878      case _VG_USERREQ__HG_SET_MY_PTHREAD_T: {
4879         Thread* my_thr = NULL;
4880         if (0)
4881         VG_(printf)("SET_MY_PTHREAD_T (tid %d): pthread_t = %p\n", (Int)tid,
4882                     (void*)args[1]);
4883         map_pthread_t_to_Thread_INIT();
4884         my_thr = map_threads_maybe_lookup( tid );
4885         /* This assertion should hold because the map_threads (tid to
4886            Thread*) binding should have been made at the point of
4887            low-level creation of this thread, which should have
4888            happened prior to us getting this client request for it.
4889            That's because this client request is sent from
4890            client-world from the 'thread_wrapper' function, which
4891            only runs once the thread has been low-level created. */
4892         tl_assert(my_thr != NULL);
4893         /* So now we know that (pthread_t)args[1] is associated with
4894            (Thread*)my_thr.  Note that down. */
4895         if (0)
4896         VG_(printf)("XXXX: bind pthread_t %p to Thread* %p\n",
4897                     (void*)args[1], (void*)my_thr );
4898         VG_(addToFM)( map_pthread_t_to_Thread, (UWord)args[1], (UWord)my_thr );
4899         break;
4900      }
4901
4902      case _VG_USERREQ__HG_PTH_API_ERROR: {
4903         Thread* my_thr = NULL;
4904         map_pthread_t_to_Thread_INIT();
4905         my_thr = map_threads_maybe_lookup( tid );
4906         tl_assert(my_thr); /* See justification above in SET_MY_PTHREAD_T */
4907         HG_(record_error_PthAPIerror)(
4908            my_thr, (HChar*)args[1], (UWord)args[2], (HChar*)args[3] );
4909         break;
4910      }
4911
4912      /* This thread (tid) has completed a join with the quitting
4913         thread whose pthread_t is in args[1]. */
4914      case _VG_USERREQ__HG_PTHREAD_JOIN_POST: {
4915         Thread* thr_q = NULL; /* quitter Thread* */
4916         Bool    found = False;
4917         if (0)
4918         VG_(printf)("NOTIFY_JOIN_COMPLETE (tid %d): quitter = %p\n", (Int)tid,
4919                     (void*)args[1]);
4920         map_pthread_t_to_Thread_INIT();
4921         found = VG_(lookupFM)( map_pthread_t_to_Thread,
4922                                NULL, (UWord*)&thr_q, (UWord)args[1] );
4923          /* Can this fail?  It would mean that our pthread_join
4924             wrapper observed a successful join on args[1] yet that
4925             thread never existed (or at least, it never lodged an
4926             entry in the mapping (via SET_MY_PTHREAD_T)).  Which
4927             sounds like a bug in the threads library. */
4928         // FIXME: get rid of this assertion; handle properly
4929         tl_assert(found);
4930         if (found) {
4931            if (0)
4932            VG_(printf)(".................... quitter Thread* = %p\n",
4933                        thr_q);
4934            evh__HG_PTHREAD_JOIN_POST( tid, thr_q );
4935         }
4936         break;
4937      }
4938
4939      /* EXPOSITION only: by intercepting lock init events we can show
4940         the user where the lock was initialised, rather than only
4941         being able to show where it was first locked.  Intercepting
4942         lock initialisations is not necessary for the basic operation
4943         of the race checker. */
4944      case _VG_USERREQ__HG_PTHREAD_MUTEX_INIT_POST:
4945         evh__HG_PTHREAD_MUTEX_INIT_POST( tid, (void*)args[1], args[2] );
4946         break;
4947
4948      /* mutex=arg[1], mutex_is_init=arg[2] */
4949      case _VG_USERREQ__HG_PTHREAD_MUTEX_DESTROY_PRE:
4950         evh__HG_PTHREAD_MUTEX_DESTROY_PRE( tid, (void*)args[1], args[2] != 0 );
4951         break;
4952
4953      case _VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_PRE:   // pth_mx_t*
4954         evh__HG_PTHREAD_MUTEX_UNLOCK_PRE( tid, (void*)args[1] );
4955         break;
4956
4957      case _VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_POST:  // pth_mx_t*
4958         evh__HG_PTHREAD_MUTEX_UNLOCK_POST( tid, (void*)args[1] );
4959         break;
4960
4961      case _VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_PRE:     // pth_mx_t*, Word
4962         evh__HG_PTHREAD_MUTEX_LOCK_PRE( tid, (void*)args[1], args[2] );
4963         break;
4964
4965      case _VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_POST:    // pth_mx_t*
4966         evh__HG_PTHREAD_MUTEX_LOCK_POST( tid, (void*)args[1] );
4967         break;
4968
4969      /* This thread is about to do pthread_cond_signal on the
4970         pthread_cond_t* in arg[1].  Ditto pthread_cond_broadcast. */
4971      case _VG_USERREQ__HG_PTHREAD_COND_SIGNAL_PRE:
4972      case _VG_USERREQ__HG_PTHREAD_COND_BROADCAST_PRE:
4973         evh__HG_PTHREAD_COND_SIGNAL_PRE( tid, (void*)args[1] );
4974         break;
4975
4976      /* Entry into pthread_cond_wait, cond=arg[1], mutex=arg[2].
4977         Returns a flag indicating whether or not the mutex is believed to be
4978         valid for this operation. */
4979      case _VG_USERREQ__HG_PTHREAD_COND_WAIT_PRE: {
4980         Bool mutex_is_valid
4981            = evh__HG_PTHREAD_COND_WAIT_PRE( tid, (void*)args[1],
4982                                                  (void*)args[2] );
4983         *ret = mutex_is_valid ? 1 : 0;
4984         break;
4985      }
4986
4987      /* Thread successfully completed pthread_cond_init:
4988         cond=arg[1], cond_attr=arg[2] */
4989      case _VG_USERREQ__HG_PTHREAD_COND_INIT_POST:
4990         evh__HG_PTHREAD_COND_INIT_POST( tid,
4991                                         (void*)args[1], (void*)args[2] );
4992	 break;
4993
4994      /* cond=arg[1], cond_is_init=arg[2] */
4995      case _VG_USERREQ__HG_PTHREAD_COND_DESTROY_PRE:
4996         evh__HG_PTHREAD_COND_DESTROY_PRE( tid, (void*)args[1], args[2] != 0 );
4997         break;
4998
4999      /* Thread successfully completed pthread_cond_wait, cond=arg[1],
5000         mutex=arg[2] */
5001      case _VG_USERREQ__HG_PTHREAD_COND_WAIT_POST:
5002         evh__HG_PTHREAD_COND_WAIT_POST( tid,
5003                                         (void*)args[1], (void*)args[2],
5004                                         (Bool)args[3] );
5005         break;
5006
5007      case _VG_USERREQ__HG_PTHREAD_RWLOCK_INIT_POST:
5008         evh__HG_PTHREAD_RWLOCK_INIT_POST( tid, (void*)args[1] );
5009         break;
5010
5011      case _VG_USERREQ__HG_PTHREAD_RWLOCK_DESTROY_PRE:
5012         evh__HG_PTHREAD_RWLOCK_DESTROY_PRE( tid, (void*)args[1] );
5013         break;
5014
5015      /* rwlock=arg[1], isW=arg[2], isTryLock=arg[3] */
5016      case _VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE:
5017         evh__HG_PTHREAD_RWLOCK_LOCK_PRE( tid, (void*)args[1],
5018                                               args[2], args[3] );
5019         break;
5020
5021      /* rwlock=arg[1], isW=arg[2] */
5022      case _VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST:
5023         evh__HG_PTHREAD_RWLOCK_LOCK_POST( tid, (void*)args[1], args[2] );
5024         break;
5025
5026      case _VG_USERREQ__HG_PTHREAD_RWLOCK_UNLOCK_PRE:
5027         evh__HG_PTHREAD_RWLOCK_UNLOCK_PRE( tid, (void*)args[1] );
5028         break;
5029
5030      case _VG_USERREQ__HG_PTHREAD_RWLOCK_UNLOCK_POST:
5031         evh__HG_PTHREAD_RWLOCK_UNLOCK_POST( tid, (void*)args[1] );
5032         break;
5033
5034      case _VG_USERREQ__HG_POSIX_SEM_INIT_POST: /* sem_t*, unsigned long */
5035         evh__HG_POSIX_SEM_INIT_POST( tid, (void*)args[1], args[2] );
5036         break;
5037
5038      case _VG_USERREQ__HG_POSIX_SEM_DESTROY_PRE: /* sem_t* */
5039         evh__HG_POSIX_SEM_DESTROY_PRE( tid, (void*)args[1] );
5040         break;
5041
5042      case _VG_USERREQ__HG_POSIX_SEM_POST_PRE: /* sem_t* */
5043         evh__HG_POSIX_SEM_POST_PRE( tid, (void*)args[1] );
5044         break;
5045
5046      case _VG_USERREQ__HG_POSIX_SEM_WAIT_POST: /* sem_t* */
5047         evh__HG_POSIX_SEM_WAIT_POST( tid, (void*)args[1] );
5048         break;
5049
5050      case _VG_USERREQ__HG_PTHREAD_BARRIER_INIT_PRE:
5051         /* pth_bar_t*, ulong count, ulong resizable */
5052         evh__HG_PTHREAD_BARRIER_INIT_PRE( tid, (void*)args[1],
5053                                                args[2], args[3] );
5054         break;
5055
5056      case _VG_USERREQ__HG_PTHREAD_BARRIER_RESIZE_PRE:
5057         /* pth_bar_t*, ulong newcount */
5058         evh__HG_PTHREAD_BARRIER_RESIZE_PRE ( tid, (void*)args[1],
5059                                              args[2] );
5060         break;
5061
5062      case _VG_USERREQ__HG_PTHREAD_BARRIER_WAIT_PRE:
5063         /* pth_bar_t* */
5064         evh__HG_PTHREAD_BARRIER_WAIT_PRE( tid, (void*)args[1] );
5065         break;
5066
5067      case _VG_USERREQ__HG_PTHREAD_BARRIER_DESTROY_PRE:
5068         /* pth_bar_t* */
5069         evh__HG_PTHREAD_BARRIER_DESTROY_PRE( tid, (void*)args[1] );
5070         break;
5071
5072      case _VG_USERREQ__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE:
5073         /* pth_spinlock_t* */
5074         evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE( tid, (void*)args[1] );
5075         break;
5076
5077      case _VG_USERREQ__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_POST:
5078         /* pth_spinlock_t* */
5079         evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_POST( tid, (void*)args[1] );
5080         break;
5081
5082      case _VG_USERREQ__HG_PTHREAD_SPIN_LOCK_PRE:
5083         /* pth_spinlock_t*, Word */
5084         evh__HG_PTHREAD_SPIN_LOCK_PRE( tid, (void*)args[1], args[2] );
5085         break;
5086
5087      case _VG_USERREQ__HG_PTHREAD_SPIN_LOCK_POST:
5088         /* pth_spinlock_t* */
5089         evh__HG_PTHREAD_SPIN_LOCK_POST( tid, (void*)args[1] );
5090         break;
5091
5092      case _VG_USERREQ__HG_PTHREAD_SPIN_DESTROY_PRE:
5093         /* pth_spinlock_t* */
5094         evh__HG_PTHREAD_SPIN_DESTROY_PRE( tid, (void*)args[1] );
5095         break;
5096
5097      case _VG_USERREQ__HG_CLIENTREQ_UNIMP: {
5098         /* HChar* who */
5099         HChar*  who = (HChar*)args[1];
5100         HChar   buf[50 + 50];
5101         Thread* thr = map_threads_maybe_lookup( tid );
5102         tl_assert( thr ); /* I must be mapped */
5103         tl_assert( who );
5104         tl_assert( VG_(strlen)(who) <= 50 );
5105         VG_(sprintf)(buf, "Unimplemented client request macro \"%s\"", who );
5106         /* record_error_Misc strdup's buf, so this is safe: */
5107         HG_(record_error_Misc)( thr, buf );
5108         break;
5109      }
5110
5111      case _VG_USERREQ__HG_USERSO_SEND_PRE:
5112         /* UWord arbitrary-SO-tag */
5113         evh__HG_USERSO_SEND_PRE( tid, args[1] );
5114         break;
5115
5116      case _VG_USERREQ__HG_USERSO_RECV_POST:
5117         /* UWord arbitrary-SO-tag */
5118         evh__HG_USERSO_RECV_POST( tid, args[1] );
5119         break;
5120
5121      case _VG_USERREQ__HG_USERSO_FORGET_ALL:
5122         /* UWord arbitrary-SO-tag */
5123         evh__HG_USERSO_FORGET_ALL( tid, args[1] );
5124         break;
5125
5126      case VG_USERREQ__GDB_MONITOR_COMMAND: {
5127         Bool handled = handle_gdb_monitor_command (tid, (HChar*)args[1]);
5128         if (handled)
5129            *ret = 1;
5130         else
5131            *ret = 0;
5132         return handled;
5133      }
5134
5135      default:
5136         /* Unhandled Helgrind client request! */
5137         tl_assert2(0, "unhandled Helgrind client request 0x%lx",
5138                       args[0]);
5139   }
5140
5141   return True;
5142}
5143
5144
5145/*----------------------------------------------------------------*/
5146/*--- Setup                                                    ---*/
5147/*----------------------------------------------------------------*/
5148
5149static Bool hg_process_cmd_line_option ( const HChar* arg )
5150{
5151   const HChar* tmp_str;
5152
5153   if      VG_BOOL_CLO(arg, "--track-lockorders",
5154                            HG_(clo_track_lockorders)) {}
5155   else if VG_BOOL_CLO(arg, "--cmp-race-err-addrs",
5156                            HG_(clo_cmp_race_err_addrs)) {}
5157
5158   else if VG_XACT_CLO(arg, "--history-level=none",
5159                            HG_(clo_history_level), 0);
5160   else if VG_XACT_CLO(arg, "--history-level=approx",
5161                            HG_(clo_history_level), 1);
5162   else if VG_XACT_CLO(arg, "--history-level=full",
5163                            HG_(clo_history_level), 2);
5164
5165   /* If you change the 10k/30mill limits, remember to also change
5166      them in assertions at the top of event_map_maybe_GC. */
5167   else if VG_BINT_CLO(arg, "--conflict-cache-size",
5168                       HG_(clo_conflict_cache_size), 10*1000, 30*1000*1000) {}
5169
5170   /* "stuvwx" --> stuvwx (binary) */
5171   else if VG_STR_CLO(arg, "--hg-sanity-flags", tmp_str) {
5172      Int j;
5173
5174      if (6 != VG_(strlen)(tmp_str)) {
5175         VG_(message)(Vg_UserMsg,
5176                      "--hg-sanity-flags argument must have 6 digits\n");
5177         return False;
5178      }
5179      for (j = 0; j < 6; j++) {
5180         if      ('0' == tmp_str[j]) { /* do nothing */ }
5181         else if ('1' == tmp_str[j]) HG_(clo_sanity_flags) |= (1 << (6-1-j));
5182         else {
5183            VG_(message)(Vg_UserMsg, "--hg-sanity-flags argument can "
5184                                     "only contain 0s and 1s\n");
5185            return False;
5186         }
5187      }
5188      if (0) VG_(printf)("XXX sanity flags: 0x%lx\n", HG_(clo_sanity_flags));
5189   }
5190
5191   else if VG_BOOL_CLO(arg, "--free-is-write",
5192                            HG_(clo_free_is_write)) {}
5193
5194   else if VG_XACT_CLO(arg, "--vts-pruning=never",
5195                            HG_(clo_vts_pruning), 0);
5196   else if VG_XACT_CLO(arg, "--vts-pruning=auto",
5197                            HG_(clo_vts_pruning), 1);
5198   else if VG_XACT_CLO(arg, "--vts-pruning=always",
5199                            HG_(clo_vts_pruning), 2);
5200
5201   else if VG_BOOL_CLO(arg, "--check-stack-refs",
5202                            HG_(clo_check_stack_refs)) {}
5203
5204   else
5205      return VG_(replacement_malloc_process_cmd_line_option)(arg);
5206
5207   return True;
5208}
5209
5210static void hg_print_usage ( void )
5211{
5212   VG_(printf)(
5213"    --free-is-write=no|yes    treat heap frees as writes [no]\n"
5214"    --track-lockorders=no|yes show lock ordering errors? [yes]\n"
5215"    --history-level=none|approx|full [full]\n"
5216"       full:   show both stack traces for a data race (can be very slow)\n"
5217"       approx: full trace for one thread, approx for the other (faster)\n"
5218"       none:   only show trace for one thread in a race (fastest)\n"
5219"    --conflict-cache-size=N   size of 'full' history cache [1000000]\n"
5220"    --check-stack-refs=no|yes race-check reads and writes on the\n"
5221"                              main stack and thread stacks? [yes]\n"
5222   );
5223}
5224
5225static void hg_print_debug_usage ( void )
5226{
5227   VG_(printf)("    --cmp-race-err-addrs=no|yes  are data addresses in "
5228               "race errors significant? [no]\n");
5229   VG_(printf)("    --hg-sanity-flags=<XXXXXX>   sanity check "
5230               "  at events (X = 0|1) [000000]\n");
5231   VG_(printf)("    --hg-sanity-flags values:\n");
5232   VG_(printf)("       010000   after changes to "
5233               "lock-order-acquisition-graph\n");
5234   VG_(printf)("       001000   at memory accesses (NB: not currently used)\n");
5235   VG_(printf)("       000100   at mem permission setting for "
5236               "ranges >= %d bytes\n", SCE_BIGRANGE_T);
5237   VG_(printf)("       000010   at lock/unlock events\n");
5238   VG_(printf)("       000001   at thread create/join events\n");
5239   VG_(printf)(
5240"    --vts-pruning=never|auto|always [auto]\n"
5241"       never:   is never done (may cause big space leaks in Helgrind)\n"
5242"       auto:    done just often enough to keep space usage under control\n"
5243"       always:  done after every VTS GC (mostly just a big time waster)\n"
5244    );
5245}
5246
5247static void hg_print_stats (void)
5248{
5249
5250   if (1) {
5251      VG_(printf)("\n");
5252      HG_(ppWSUstats)( univ_lsets, "univ_lsets" );
5253      if (HG_(clo_track_lockorders)) {
5254         VG_(printf)("\n");
5255         HG_(ppWSUstats)( univ_laog,  "univ_laog" );
5256      }
5257   }
5258
5259   //zz       VG_(printf)("\n");
5260   //zz       VG_(printf)(" hbefore: %'10lu queries\n",        stats__hbefore_queries);
5261   //zz       VG_(printf)(" hbefore: %'10lu cache 0 hits\n",   stats__hbefore_cache0s);
5262   //zz       VG_(printf)(" hbefore: %'10lu cache > 0 hits\n", stats__hbefore_cacheNs);
5263   //zz       VG_(printf)(" hbefore: %'10lu graph searches\n", stats__hbefore_gsearches);
5264   //zz       VG_(printf)(" hbefore: %'10lu   of which slow\n",
5265   //zz                   stats__hbefore_gsearches - stats__hbefore_gsearchFs);
5266   //zz       VG_(printf)(" hbefore: %'10lu stack high water mark\n",
5267   //zz                   stats__hbefore_stk_hwm);
5268   //zz       VG_(printf)(" hbefore: %'10lu cache invals\n",   stats__hbefore_invals);
5269   //zz       VG_(printf)(" hbefore: %'10lu probes\n",         stats__hbefore_probes);
5270
5271   VG_(printf)("\n");
5272   VG_(printf)("        locksets: %'8d unique lock sets\n",
5273               (Int)HG_(cardinalityWSU)( univ_lsets ));
5274   if (HG_(clo_track_lockorders)) {
5275      VG_(printf)("       univ_laog: %'8d unique lock sets\n",
5276                  (Int)HG_(cardinalityWSU)( univ_laog ));
5277   }
5278
5279   //VG_(printf)("L(ast)L(ock) map: %'8lu inserts (%d map size)\n",
5280   //            stats__ga_LL_adds,
5281   //            (Int)(ga_to_lastlock ? VG_(sizeFM)( ga_to_lastlock ) : 0) );
5282
5283   VG_(printf)("  LockN-to-P map: %'8llu queries (%llu map size)\n",
5284               HG_(stats__LockN_to_P_queries),
5285               HG_(stats__LockN_to_P_get_map_size)() );
5286
5287   VG_(printf)("string table map: %'8llu queries (%llu map size)\n",
5288               HG_(stats__string_table_queries),
5289               HG_(stats__string_table_get_map_size)() );
5290   if (HG_(clo_track_lockorders)) {
5291      VG_(printf)("            LAOG: %'8d map size\n",
5292                  (Int)(laog ? VG_(sizeFM)( laog ) : 0));
5293      VG_(printf)(" LAOG exposition: %'8d map size\n",
5294                  (Int)(laog_exposition ? VG_(sizeFM)( laog_exposition ) : 0));
5295   }
5296
5297   VG_(printf)("           locks: %'8lu acquires, "
5298               "%'lu releases\n",
5299               stats__lockN_acquires,
5300               stats__lockN_releases
5301              );
5302   VG_(printf)("   sanity checks: %'8lu\n", stats__sanity_checks);
5303
5304   VG_(printf)("\n");
5305   libhb_shutdown(True); // This in fact only print stats.
5306}
5307
5308static void hg_fini ( Int exitcode )
5309{
5310   if (VG_(clo_verbosity) == 1 && !VG_(clo_xml)) {
5311      VG_(message)(Vg_UserMsg,
5312                   "For counts of detected and suppressed errors, "
5313                   "rerun with: -v\n");
5314   }
5315
5316   if (VG_(clo_verbosity) == 1 && !VG_(clo_xml)
5317       && HG_(clo_history_level) >= 2) {
5318      VG_(umsg)(
5319         "Use --history-level=approx or =none to gain increased speed, at\n" );
5320      VG_(umsg)(
5321         "the cost of reduced accuracy of conflicting-access information\n");
5322   }
5323
5324   if (SHOW_DATA_STRUCTURES)
5325      pp_everything( PP_ALL, "SK_(fini)" );
5326   if (HG_(clo_sanity_flags))
5327      all__sanity_check("SK_(fini)");
5328
5329   if (VG_(clo_stats))
5330      hg_print_stats();
5331}
5332
5333/* FIXME: move these somewhere sane */
5334
5335static
5336void for_libhb__get_stacktrace ( Thr* hbt, Addr* frames, UWord nRequest )
5337{
5338   Thread*     thr;
5339   ThreadId    tid;
5340   UWord       nActual;
5341   tl_assert(hbt);
5342   thr = libhb_get_Thr_hgthread( hbt );
5343   tl_assert(thr);
5344   tid = map_threads_maybe_reverse_lookup_SLOW(thr);
5345   nActual = (UWord)VG_(get_StackTrace)( tid, frames, (UInt)nRequest,
5346                                         NULL, NULL, 0 );
5347   tl_assert(nActual <= nRequest);
5348   for (; nActual < nRequest; nActual++)
5349      frames[nActual] = 0;
5350}
5351
5352static
5353ExeContext* for_libhb__get_EC ( Thr* hbt )
5354{
5355   Thread*     thr;
5356   ThreadId    tid;
5357   ExeContext* ec;
5358   tl_assert(hbt);
5359   thr = libhb_get_Thr_hgthread( hbt );
5360   tl_assert(thr);
5361   tid = map_threads_maybe_reverse_lookup_SLOW(thr);
5362   /* this will assert if tid is invalid */
5363   ec = VG_(record_ExeContext)( tid, 0 );
5364   return ec;
5365}
5366
5367
5368static void hg_post_clo_init ( void )
5369{
5370   Thr* hbthr_root;
5371
5372   /////////////////////////////////////////////
5373   hbthr_root = libhb_init( for_libhb__get_stacktrace,
5374                            for_libhb__get_EC );
5375   /////////////////////////////////////////////
5376
5377
5378   if (HG_(clo_track_lockorders))
5379      laog__init();
5380
5381   initialise_data_structures(hbthr_root);
5382}
5383
5384static void hg_info_location (Addr a)
5385{
5386   (void) HG_(get_and_pp_addrdescr) (a);
5387}
5388
5389static void hg_pre_clo_init ( void )
5390{
5391   VG_(details_name)            ("Helgrind");
5392   VG_(details_version)         (NULL);
5393   VG_(details_description)     ("a thread error detector");
5394   VG_(details_copyright_author)(
5395      "Copyright (C) 2007-2013, and GNU GPL'd, by OpenWorks LLP et al.");
5396   VG_(details_bug_reports_to)  (VG_BUGS_TO);
5397   VG_(details_avg_translation_sizeB) ( 320 );
5398
5399   VG_(basic_tool_funcs)          (hg_post_clo_init,
5400                                   hg_instrument,
5401                                   hg_fini);
5402
5403   VG_(needs_core_errors)         ();
5404   VG_(needs_tool_errors)         (HG_(eq_Error),
5405                                   HG_(before_pp_Error),
5406                                   HG_(pp_Error),
5407                                   False,/*show TIDs for errors*/
5408                                   HG_(update_extra),
5409                                   HG_(recognised_suppression),
5410                                   HG_(read_extra_suppression_info),
5411                                   HG_(error_matches_suppression),
5412                                   HG_(get_error_name),
5413                                   HG_(get_extra_suppression_info),
5414                                   HG_(print_extra_suppression_use),
5415                                   HG_(update_extra_suppression_use));
5416
5417   VG_(needs_xml_output)          ();
5418
5419   VG_(needs_command_line_options)(hg_process_cmd_line_option,
5420                                   hg_print_usage,
5421                                   hg_print_debug_usage);
5422   VG_(needs_client_requests)     (hg_handle_client_request);
5423
5424   // FIXME?
5425   //VG_(needs_sanity_checks)       (hg_cheap_sanity_check,
5426   //                                hg_expensive_sanity_check);
5427
5428   VG_(needs_print_stats) (hg_print_stats);
5429   VG_(needs_info_location) (hg_info_location);
5430
5431   VG_(needs_malloc_replacement)  (hg_cli__malloc,
5432                                   hg_cli____builtin_new,
5433                                   hg_cli____builtin_vec_new,
5434                                   hg_cli__memalign,
5435                                   hg_cli__calloc,
5436                                   hg_cli__free,
5437                                   hg_cli____builtin_delete,
5438                                   hg_cli____builtin_vec_delete,
5439                                   hg_cli__realloc,
5440                                   hg_cli_malloc_usable_size,
5441                                   HG_CLI__DEFAULT_MALLOC_REDZONE_SZB );
5442
5443   /* 21 Dec 08: disabled this; it mostly causes H to start more
5444      slowly and use significantly more memory, without very often
5445      providing useful results.  The user can request to load this
5446      information manually with --read-var-info=yes. */
5447   if (0) VG_(needs_var_info)(); /* optional */
5448
5449   VG_(track_new_mem_startup)     ( evh__new_mem_w_perms );
5450   VG_(track_new_mem_stack_signal)( evh__new_mem_w_tid );
5451   VG_(track_new_mem_brk)         ( evh__new_mem_w_tid );
5452   VG_(track_new_mem_mmap)        ( evh__new_mem_w_perms );
5453   VG_(track_new_mem_stack)       ( evh__new_mem_stack );
5454
5455   // FIXME: surely this isn't thread-aware
5456   VG_(track_copy_mem_remap)      ( evh__copy_mem );
5457
5458   VG_(track_change_mem_mprotect) ( evh__set_perms );
5459
5460   VG_(track_die_mem_stack_signal)( evh__die_mem );
5461   VG_(track_die_mem_brk)         ( evh__die_mem_munmap );
5462   VG_(track_die_mem_munmap)      ( evh__die_mem_munmap );
5463   VG_(track_die_mem_stack)       ( evh__die_mem );
5464
5465   // FIXME: what is this for?
5466   VG_(track_ban_mem_stack)       (NULL);
5467
5468   VG_(track_pre_mem_read)        ( evh__pre_mem_read );
5469   VG_(track_pre_mem_read_asciiz) ( evh__pre_mem_read_asciiz );
5470   VG_(track_pre_mem_write)       ( evh__pre_mem_write );
5471   VG_(track_post_mem_write)      (NULL);
5472
5473   /////////////////
5474
5475   VG_(track_pre_thread_ll_create)( evh__pre_thread_ll_create );
5476   VG_(track_pre_thread_ll_exit)  ( evh__pre_thread_ll_exit );
5477
5478   VG_(track_start_client_code)( evh__start_client_code );
5479   VG_(track_stop_client_code)( evh__stop_client_code );
5480
5481   /* Ensure that requirements for "dodgy C-as-C++ style inheritance"
5482      as described in comments at the top of pub_tool_hashtable.h, are
5483      met.  Blargh. */
5484   tl_assert( sizeof(void*) == sizeof(struct _MallocMeta*) );
5485   tl_assert( sizeof(UWord) == sizeof(Addr) );
5486   hg_mallocmeta_table
5487      = VG_(HT_construct)( "hg_malloc_metadata_table" );
5488
5489   MallocMeta_poolalloc = VG_(newPA) ( sizeof(MallocMeta),
5490                                       1000,
5491                                       HG_(zalloc),
5492                                       "hg_malloc_metadata_pool",
5493                                       HG_(free));
5494
5495   // add a callback to clean up on (threaded) fork.
5496   VG_(atfork)(NULL/*pre*/, NULL/*parent*/, evh__atfork_child/*child*/);
5497}
5498
5499VG_DETERMINE_INTERFACE_VERSION(hg_pre_clo_init)
5500
5501/*--------------------------------------------------------------------*/
5502/*--- end                                                hg_main.c ---*/
5503/*--------------------------------------------------------------------*/
5504