/*
  This file is part of drd, a thread error detector.

  Copyright (C) 2006-2011 Bart Van Assche <bvanassche@acm.org>.

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

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

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

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


#include "drd_bitmap.h"
#include "drd_thread_bitmap.h"
#include "drd_vc.h"            /* DRD_(vc_snprint)() */

/* Include several source files here in order to allow the compiler to */
/* do more inlining.                                                   */
#include "drd_bitmap.c"
#include "drd_load_store.h"
#include "drd_segment.c"
#include "drd_thread.c"
#include "drd_vc.c"
#include "libvex_guest_offsets.h"


/* STACK_POINTER_OFFSET: VEX register offset for the stack pointer register. */
#if defined(VGA_x86)
#define STACK_POINTER_OFFSET OFFSET_x86_ESP
#elif defined(VGA_amd64)
#define STACK_POINTER_OFFSET OFFSET_amd64_RSP
#elif defined(VGA_ppc32)
#define STACK_POINTER_OFFSET OFFSET_ppc32_GPR1
#elif defined(VGA_ppc64)
#define STACK_POINTER_OFFSET OFFSET_ppc64_GPR1
#elif defined(VGA_arm)
#define STACK_POINTER_OFFSET OFFSET_arm_R13
#elif defined(VGA_s390x)
#define STACK_POINTER_OFFSET OFFSET_s390x_r15
#else
#error Unknown architecture.
#endif


/* Local variables. */

static Bool s_check_stack_accesses = False;
static Bool s_first_race_only      = False;


/* Function definitions. */

Bool DRD_(get_check_stack_accesses)()
{
   return s_check_stack_accesses;
}

void DRD_(set_check_stack_accesses)(const Bool c)
{
   tl_assert(c == False || c == True);
   s_check_stack_accesses = c;
}

Bool DRD_(get_first_race_only)()
{
   return s_first_race_only;
}

void DRD_(set_first_race_only)(const Bool fro)
{
   tl_assert(fro == False || fro == True);
   s_first_race_only = fro;
}

void DRD_(trace_mem_access)(const Addr addr, const SizeT size,
                            const BmAccessTypeT access_type)
{
   if (DRD_(is_any_traced)(addr, addr + size))
   {
      char* vc;

      vc = DRD_(vc_aprint)(DRD_(thread_get_vc)(DRD_(thread_get_running_tid)()));
      DRD_(trace_msg_w_bt)("%s 0x%lx size %ld (thread %d / vc %s)",
                           access_type == eLoad ? "load "
                           : access_type == eStore ? "store"
                           : access_type == eStart ? "start"
                           : access_type == eEnd ? "end  " : "????",
                           addr, size, DRD_(thread_get_running_tid)(), vc);
      VG_(free)(vc);
      tl_assert(DRD_(DrdThreadIdToVgThreadId)(DRD_(thread_get_running_tid)())
                == VG_(get_running_tid)());
   }
}

static VG_REGPARM(2) void drd_trace_mem_load(const Addr addr, const SizeT size)
{
   return DRD_(trace_mem_access)(addr, size, eLoad);
}

static VG_REGPARM(2) void drd_trace_mem_store(const Addr addr,const SizeT size)
{
   return DRD_(trace_mem_access)(addr, size, eStore);
}

static void drd_report_race(const Addr addr, const SizeT size,
                            const BmAccessTypeT access_type)
{
   DataRaceErrInfo drei;

   drei.tid  = DRD_(thread_get_running_tid)();
   drei.addr = addr;
   drei.size = size;
   drei.access_type = access_type;
   VG_(maybe_record_error)(VG_(get_running_tid)(),
                           DataRaceErr,
                           VG_(get_IP)(VG_(get_running_tid)()),
                           "Conflicting access",
                           &drei);

   if (s_first_race_only)
   {
      DRD_(start_suppression)(addr, addr + size, "first race only");
   }
}

VG_REGPARM(2) void DRD_(trace_load)(Addr addr, SizeT size)
{
#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
   /* The assert below has been commented out because of performance reasons.*/
   tl_assert(DRD_(thread_get_running_tid)()
             == DRD_(VgThreadIdToDrdThreadId)(VG_(get_running_tid())));
#endif

   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_triggers_conflict(addr, addr + size)
       && ! DRD_(is_suppressed)(addr, addr + size))
   {
      drd_report_race(addr, size, eLoad);
   }
}

static VG_REGPARM(1) void drd_trace_load_1(Addr addr)
{
   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_1_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 1))
   {
      drd_report_race(addr, 1, eLoad);
   }
}

static VG_REGPARM(1) void drd_trace_load_2(Addr addr)
{
   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_2_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 2))
   {
      drd_report_race(addr, 2, eLoad);
   }
}

static VG_REGPARM(1) void drd_trace_load_4(Addr addr)
{
   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_4_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 4))
   {
      drd_report_race(addr, 4, eLoad);
   }
}

static VG_REGPARM(1) void drd_trace_load_8(Addr addr)
{
   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_8_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 8))
   {
      drd_report_race(addr, 8, eLoad);
   }
}

VG_REGPARM(2) void DRD_(trace_store)(Addr addr, SizeT size)
{
#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
   /* The assert below has been commented out because of performance reasons.*/
   tl_assert(DRD_(thread_get_running_tid)()
             == DRD_(VgThreadIdToDrdThreadId)(VG_(get_running_tid())));
#endif

   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_store_triggers_conflict(addr, addr + size)
       && ! DRD_(is_suppressed)(addr, addr + size))
   {
      drd_report_race(addr, size, eStore);
   }
}

static VG_REGPARM(1) void drd_trace_store_1(Addr addr)
{
   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_store_1_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 1))
   {
      drd_report_race(addr, 1, eStore);
   }
}

static VG_REGPARM(1) void drd_trace_store_2(Addr addr)
{
   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_store_2_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 2))
   {
      drd_report_race(addr, 2, eStore);
   }
}

static VG_REGPARM(1) void drd_trace_store_4(Addr addr)
{
   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_store_4_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 4))
   {
      drd_report_race(addr, 4, eStore);
   }
}

static VG_REGPARM(1) void drd_trace_store_8(Addr addr)
{
   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_store_8_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 8))
   {
      drd_report_race(addr, 8, eStore);
   }
}

/**
 * Return true if and only if addr_expr matches the pattern (SP) or
 * <offset>(SP).
 */
static Bool is_stack_access(IRSB* const bb, IRExpr* const addr_expr)
{
   Bool result = False;

   if (addr_expr->tag == Iex_RdTmp)
   {
      int i;
      for (i = 0; i < bb->stmts_size; i++)
      {
         if (bb->stmts[i]
             && bb->stmts[i]->tag == Ist_WrTmp
             && bb->stmts[i]->Ist.WrTmp.tmp == addr_expr->Iex.RdTmp.tmp)
         {
            IRExpr* e = bb->stmts[i]->Ist.WrTmp.data;
            if (e->tag == Iex_Get && e->Iex.Get.offset == STACK_POINTER_OFFSET)
            {
               result = True;
            }

            //ppIRExpr(e);
            //VG_(printf)(" (%s)\n", result ? "True" : "False");
            break;
         }
      }
   }
   return result;
}

static void instrument_load(IRSB* const bb,
                            IRExpr* const addr_expr,
                            const HWord size)
{
   IRExpr* size_expr;
   IRExpr** argv;
   IRDirty* di;

   if (UNLIKELY(DRD_(any_address_is_traced)()))
   {
      addStmtToIRSB(bb,
         IRStmt_Dirty(
            unsafeIRDirty_0_N(/*regparms*/2,
                              "drd_trace_load",
                              VG_(fnptr_to_fnentry)
                              (drd_trace_mem_load),
                              mkIRExprVec_2(addr_expr,
                                            mkIRExpr_HWord(size)))));
   }

   if (! s_check_stack_accesses && is_stack_access(bb, addr_expr))
      return;

   switch (size)
   {
   case 1:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_load_1",
                             VG_(fnptr_to_fnentry)(drd_trace_load_1),
                             argv);
      break;
   case 2:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_load_2",
                             VG_(fnptr_to_fnentry)(drd_trace_load_2),
                             argv);
      break;
   case 4:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_load_4",
                             VG_(fnptr_to_fnentry)(drd_trace_load_4),
                             argv);
      break;
   case 8:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_load_8",
                             VG_(fnptr_to_fnentry)(drd_trace_load_8),
                             argv);
      break;
   default:
      size_expr = mkIRExpr_HWord(size);
      argv = mkIRExprVec_2(addr_expr, size_expr);
      di = unsafeIRDirty_0_N(/*regparms*/2,
                             "drd_trace_load",
                             VG_(fnptr_to_fnentry)(DRD_(trace_load)),
                             argv);
      break;
   }
   addStmtToIRSB(bb, IRStmt_Dirty(di));
}

static void instrument_store(IRSB* const bb,
                             IRExpr* const addr_expr,
                             const HWord size)
{
   IRExpr* size_expr;
   IRExpr** argv;
   IRDirty* di;

   if (UNLIKELY(DRD_(any_address_is_traced)()))
   {
      addStmtToIRSB(bb,
                    IRStmt_Dirty(
                                 unsafeIRDirty_0_N(/*regparms*/2,
                                                   "drd_trace_store",
                                                   VG_(fnptr_to_fnentry)
                                                   (drd_trace_mem_store),
                                                   mkIRExprVec_2(addr_expr,
                                                                 mkIRExpr_HWord(size)))));
   }

   if (! s_check_stack_accesses && is_stack_access(bb, addr_expr))
      return;

   switch (size)
   {
   case 1:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_store_1",
                             VG_(fnptr_to_fnentry)(drd_trace_store_1),
                             argv);
      break;
   case 2:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_store_2",
                             VG_(fnptr_to_fnentry)(drd_trace_store_2),
                             argv);
      break;
   case 4:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_store_4",
                             VG_(fnptr_to_fnentry)(drd_trace_store_4),
                             argv);
      break;
   case 8:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_store_8",
                             VG_(fnptr_to_fnentry)(drd_trace_store_8),
                             argv);
      break;
   default:
      size_expr = mkIRExpr_HWord(size);
      argv = mkIRExprVec_2(addr_expr, size_expr);
      di = unsafeIRDirty_0_N(/*regparms*/2,
                             "drd_trace_store",
                             VG_(fnptr_to_fnentry)(DRD_(trace_store)),
                             argv);
      break;
   }
   addStmtToIRSB(bb, IRStmt_Dirty(di));
}

IRSB* DRD_(instrument)(VgCallbackClosure* const closure,
                       IRSB* const bb_in,
                       VexGuestLayout* const layout,
                       VexGuestExtents* const vge,
                       IRType const gWordTy,
                       IRType const hWordTy)
{
   IRDirty* di;
   Int      i;
   IRSB*    bb;
   IRExpr** argv;
   Bool     instrument = True;

   /* Set up BB */
   bb           = emptyIRSB();
   bb->tyenv    = deepCopyIRTypeEnv(bb_in->tyenv);
   bb->next     = deepCopyIRExpr(bb_in->next);
   bb->jumpkind = bb_in->jumpkind;

   for (i = 0; i < bb_in->stmts_used; i++)
   {
      IRStmt* const st = bb_in->stmts[i];
      tl_assert(st);
      tl_assert(isFlatIRStmt(st));

      switch (st->tag)
      {
         /* Note: the code for not instrumenting the code in .plt          */
         /* sections is only necessary on CentOS 3.0 x86 (kernel 2.4.21    */
         /* + glibc 2.3.2 + NPTL 0.60 + binutils 2.14.90.0.4).             */
         /* This is because on this platform dynamic library symbols are   */
         /* relocated in another way than by later binutils versions. The  */
         /* linker e.g. does not generate .got.plt sections on CentOS 3.0. */
      case Ist_IMark:
         instrument = VG_(DebugInfo_sect_kind)(NULL, 0, st->Ist.IMark.addr)
            != Vg_SectPLT;
         addStmtToIRSB(bb, st);
         break;

      case Ist_MBE:
         switch (st->Ist.MBE.event)
         {
         case Imbe_Fence:
            break; /* not interesting */
         default:
            tl_assert(0);
         }
         addStmtToIRSB(bb, st);
         break;

      case Ist_Store:
         if (instrument)
         {
            instrument_store(bb,
                             st->Ist.Store.addr,
                             sizeofIRType(typeOfIRExpr(bb->tyenv,
                                                       st->Ist.Store.data)));
         }
         addStmtToIRSB(bb, st);
         break;

      case Ist_WrTmp:
         if (instrument)
         {
            const IRExpr* const data = st->Ist.WrTmp.data;
            if (data->tag == Iex_Load)
            {
               instrument_load(bb,
                               data->Iex.Load.addr,
                               sizeofIRType(data->Iex.Load.ty));
            }
         }
         addStmtToIRSB(bb, st);
         break;

      case Ist_Dirty:
         if (instrument)
         {
            IRDirty* d = st->Ist.Dirty.details;
            IREffect const mFx = d->mFx;
            switch (mFx) {
            case Ifx_None:
               break;
            case Ifx_Read:
            case Ifx_Write:
            case Ifx_Modify:
               tl_assert(d->mAddr);
               tl_assert(d->mSize > 0);
               argv = mkIRExprVec_2(d->mAddr, mkIRExpr_HWord(d->mSize));
               if (mFx == Ifx_Read || mFx == Ifx_Modify) {
                  di = unsafeIRDirty_0_N(
                          /*regparms*/2,
                          "drd_trace_load",
                          VG_(fnptr_to_fnentry)(DRD_(trace_load)),
                          argv);
                  addStmtToIRSB(bb, IRStmt_Dirty(di));
               }
               if (mFx == Ifx_Write || mFx == Ifx_Modify)
               {
                  di = unsafeIRDirty_0_N(
                          /*regparms*/2,
                          "drd_trace_store",
                          VG_(fnptr_to_fnentry)(DRD_(trace_store)),
                          argv);
                  addStmtToIRSB(bb, IRStmt_Dirty(di));
               }
               break;
            default:
               tl_assert(0);
            }
         }
         addStmtToIRSB(bb, st);
         break;

      case Ist_CAS:
         if (instrument)
         {
            /*
             * Treat compare-and-swap as a read. By handling atomic
             * instructions as read instructions no data races are reported
             * between conflicting atomic operations nor between atomic
             * operations and non-atomic reads. Conflicts between atomic
             * operations and non-atomic write operations are still reported
             * however.
             */
            Int    dataSize;
            IRCAS* cas = st->Ist.CAS.details;
            tl_assert(cas->addr != NULL);
            tl_assert(cas->dataLo != NULL);
            dataSize = sizeofIRType(typeOfIRExpr(bb->tyenv, cas->dataLo));
            if (cas->dataHi != NULL)
               dataSize *= 2; /* since it's a doubleword-CAS */
            instrument_load(bb, cas->addr, dataSize);
         }
         addStmtToIRSB(bb, st);
         break;

      case Ist_LLSC: {
         /* Ignore store-conditionals, and handle load-linked's
            exactly like normal loads. */
         IRType dataTy;
         if (st->Ist.LLSC.storedata == NULL)
         {
            /* LL */
            dataTy = typeOfIRTemp(bb_in->tyenv, st->Ist.LLSC.result);
            if (instrument) {
               instrument_load(bb,
                               st->Ist.LLSC.addr,
                               sizeofIRType(dataTy));
            }
         }
         else
         {
            /* SC */
            /*ignore */
         }
         addStmtToIRSB(bb, st);
         break;
      }

      case Ist_NoOp:
      case Ist_AbiHint:
      case Ist_Put:
      case Ist_PutI:
      case Ist_Exit:
         /* None of these can contain any memory references. */
         addStmtToIRSB(bb, st);
         break;

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

   return bb;
}

