//--------------------------------------------------------------------*/
//--- BBV: a SimPoint basic block vector generator      bbv_main.c ---*/
//--------------------------------------------------------------------*/

/*
   This file is part of BBV, a Valgrind tool for generating SimPoint
   basic block vectors.

   Copyright (C) 2006-2013 Vince Weaver
      vince _at_ csl.cornell.edu

   pcfile code is Copyright (C) 2006-2013 Oriol Prat
      oriol.prat _at _ bsc.es

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

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

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

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


#include "pub_tool_basics.h"
#include "pub_tool_tooliface.h"
#include "pub_tool_options.h"    /* command line options */

#include "pub_tool_vki.h"        /* vki_stat */
#include "pub_tool_libcbase.h"   /* VG_(strlen) */
#include "pub_tool_libcfile.h"   /* VG_(write) */
#include "pub_tool_libcprint.h"  /* VG_(printf) */
#include "pub_tool_libcassert.h" /* VG_(exit) */
#include "pub_tool_mallocfree.h" /* plain_free */
#include "pub_tool_machine.h"    /* VG_(fnptr_to_fnentry) */
#include "pub_tool_debuginfo.h"  /* VG_(get_fnname) */

#include "pub_tool_oset.h"       /* ordered set stuff */

   /* instruction special cases */
#define REP_INSTRUCTION   0x1
#define FLDCW_INSTRUCTION 0x2

   /* interval variables */
#define DEFAULT_GRAIN_SIZE 100000000  /* 100 million by default */
static Int interval_size=DEFAULT_GRAIN_SIZE;

   /* filenames */
static const HChar *clo_bb_out_file="bb.out.%p";
static const HChar *clo_pc_out_file="pc.out.%p";
static HChar *pc_out_file=NULL;
static HChar *bb_out_file=NULL;


   /* output parameters */
static Bool instr_count_only=False;
static Bool generate_pc_file=False;

   /* write buffer */
static HChar buf[1024];

   /* Global values */
static OSet* instr_info_table;  /* table that holds the basic block info */
static Int block_num=1;         /* global next block number */
static Int current_thread=0;
static Int allocated_threads=1;
struct thread_info *bbv_thread=NULL;

   /* Per-thread variables */
struct thread_info {
   ULong dyn_instr;         /* Current retired instruction count */
   ULong total_instr;       /* Total retired instruction count   */
   Addr last_rep_addr;      /* rep counting values */
   ULong rep_count;
   ULong global_rep_count;
   ULong unique_rep_count;
   ULong fldcw_count;       /* fldcw count */
   Int bbtrace_fd;          /* file descriptor */
};

#define FUNCTION_NAME_LENGTH 20

struct BB_info {
   Addr       BB_addr;           /* used as key, must be first           */
   Int        n_instrs;          /* instructions in the basic block      */
   Int        block_num;         /* unique block identifier              */
   Int        *inst_counter;     /* times entered * num_instructions     */
   Bool       is_entry;          /* is this block a function entry point */
   HChar      fn_name[FUNCTION_NAME_LENGTH];  /* Function block is in    */
};


   /* dump the optional PC file, which contains basic block number to */
   /*   instruction address and function name mappings                */
static void dumpPcFile(void)
{
   struct BB_info   *bb_elem;
   Int              pctrace_fd;
   SysRes           sres;

   pc_out_file =
          VG_(expand_file_name)("--pc-out-file", clo_pc_out_file);

   sres = VG_(open)(pc_out_file, VKI_O_CREAT|VKI_O_TRUNC|VKI_O_WRONLY,
                              VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IWGRP);
   if (sr_isError(sres)) {
      VG_(umsg)("Error: cannot create pc file %s\n", pc_out_file);
      VG_(exit)(1);
   } else {
      pctrace_fd = sr_Res(sres);
   }

      /* Loop through the table, printing the number, address, */
      /*    and function name for each basic block             */
   VG_(OSetGen_ResetIter)(instr_info_table);
   while ( (bb_elem = VG_(OSetGen_Next)(instr_info_table)) ) {
      VG_(write)(pctrace_fd,"F",1);
      VG_(sprintf)( buf,":%d:%x:%s\n",
                       bb_elem->block_num,
                       (Int)bb_elem->BB_addr,
                       bb_elem->fn_name);
      VG_(write)(pctrace_fd, (void*)buf, VG_(strlen)(buf));
   }

   VG_(close)(pctrace_fd);
}

static Int open_tracefile(Int thread_num)
{
   SysRes  sres;
   HChar temp_string[2048];

      /* For thread 1, don't append any thread number  */
      /* This lets the single-thread case not have any */
      /* extra values appended to the file name.       */
   if (thread_num==1) {
      VG_(strncpy)(temp_string,bb_out_file,2047);
   }
   else {
      VG_(sprintf)(temp_string,"%s.%d",bb_out_file,thread_num);
   }

   sres = VG_(open)(temp_string, VKI_O_CREAT|VKI_O_TRUNC|VKI_O_WRONLY,
                              VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IWGRP);

   if (sr_isError(sres)) {
      VG_(umsg)("Error: cannot create bb file %s\n",temp_string);
      VG_(exit)(1);
   }

   return sr_Res(sres);
}

static void handle_overflow(void)
{
   struct BB_info *bb_elem;

   if (bbv_thread[current_thread].dyn_instr > interval_size) {

      if (!instr_count_only) {

            /* If our output fd hasn't been opened, open it */
         if (bbv_thread[current_thread].bbtrace_fd < 0) {
            bbv_thread[current_thread].bbtrace_fd=open_tracefile(current_thread);
         }

           /* put an entry to the bb.out file */

         VG_(write)(bbv_thread[current_thread].bbtrace_fd,"T",1);

         VG_(OSetGen_ResetIter)(instr_info_table);
         while ( (bb_elem = VG_(OSetGen_Next)(instr_info_table)) ) {
            if ( bb_elem->inst_counter[current_thread] != 0 ) {
               VG_(sprintf)( buf,":%d:%d   ",
                         bb_elem->block_num,
                         bb_elem->inst_counter[current_thread]);
               VG_(write)(bbv_thread[current_thread].bbtrace_fd,
                          (void*)buf, VG_(strlen)(buf));
               bb_elem->inst_counter[current_thread] = 0;
            }
         }

         VG_(write)(bbv_thread[current_thread].bbtrace_fd,"\n",1);
      }

      bbv_thread[current_thread].dyn_instr -= interval_size;
   }
}


static void close_out_reps(void)
{
   bbv_thread[current_thread].global_rep_count+=bbv_thread[current_thread].rep_count;
   bbv_thread[current_thread].unique_rep_count++;
   bbv_thread[current_thread].rep_count=0;
}

   /* Generic function to get called each instruction */
static VG_REGPARM(1) void per_instruction_BBV(struct BB_info *bbInfo)
{
   Int n_instrs=1;

   tl_assert(bbInfo);

      /* we finished rep but didn't clear out count */
   if (bbv_thread[current_thread].rep_count) {
      n_instrs++;
      close_out_reps();
   }

   bbInfo->inst_counter[current_thread]+=n_instrs;

   bbv_thread[current_thread].total_instr+=n_instrs;
   bbv_thread[current_thread].dyn_instr +=n_instrs;

   handle_overflow();
}

   /* Function to get called if instruction has a rep prefix */
static VG_REGPARM(1) void per_instruction_BBV_rep(Addr addr)
{
      /* handle back-to-back rep instructions */
   if (bbv_thread[current_thread].last_rep_addr!=addr) {
      if (bbv_thread[current_thread].rep_count) {
         close_out_reps();
         bbv_thread[current_thread].total_instr++;
         bbv_thread[current_thread].dyn_instr++;
      }
      bbv_thread[current_thread].last_rep_addr=addr;
   }

   bbv_thread[current_thread].rep_count++;

}

   /* Function to call if our instruction has a fldcw instruction */
static VG_REGPARM(1) void per_instruction_BBV_fldcw(struct BB_info *bbInfo)
{
   Int n_instrs=1;

   tl_assert(bbInfo);

      /* we finished rep but didn't clear out count */
   if (bbv_thread[current_thread].rep_count) {
      n_instrs++;
      close_out_reps();
   }

      /* count fldcw instructions */
   bbv_thread[current_thread].fldcw_count++;

   bbInfo->inst_counter[current_thread]+=n_instrs;

   bbv_thread[current_thread].total_instr+=n_instrs;
   bbv_thread[current_thread].dyn_instr +=n_instrs;

   handle_overflow();
}

   /* Check if the instruction pointed to is one that needs */
   /*   special handling.  If so, set a bit in the return   */
   /*   value indicating what type.                         */
static Int get_inst_type(Int len, Addr addr)
{
   int result=0;

#if defined(VGA_x86) || defined(VGA_amd64)

   UChar *inst_pointer;
   UChar  inst_byte;
   int i,possible_rep;

   /* rep prefixed instructions are counted as one instruction on */
   /*     x86 processors and must be handled as a special case    */

   /* Also, the rep prefix is re-used as part of the opcode for   */
   /*     SSE instructions.  So we need to specifically check for */
   /*     the following: movs, cmps, scas, lods, stos, ins, outs  */

   inst_pointer=(UChar *)addr;
   i=0;
   inst_byte=0;
   possible_rep=0;

   while (i<len) {

      inst_byte=*inst_pointer;

      if ( (inst_byte == 0x67) ||            /* size override prefix */
           (inst_byte == 0x66) ||            /* size override prefix */
           (inst_byte == 0x48) ) {           /* 64-bit prefix */
      } else if ( (inst_byte == 0xf2) ||     /* rep prefix    */
                  (inst_byte == 0xf3) ) {    /* repne prefix  */
         possible_rep=1;
      } else {
         break;                              /* other byte, exit */
      }

      i++;
      inst_pointer++;
   }

   if ( possible_rep &&
        ( ( (inst_byte >= 0xa4) &&     /* movs,cmps,scas */
            (inst_byte <= 0xaf) ) ||   /* lods,stos      */
          ( (inst_byte >= 0x6c) &&
            (inst_byte <= 0x6f) ) ) ) {  /* ins,outs       */

      result|=REP_INSTRUCTION;
   }

   /* fldcw instructions are double-counted by the hardware       */
   /*     performance counters on pentium 4 processors so it is   */
   /*     useful to have that count when doing validation work.   */

   inst_pointer=(UChar *)addr;
   if (len>1) {
         /* FLDCW detection */
         /* opcode is 0xd9/5, ie 1101 1001 oo10 1mmm */
      if ((*inst_pointer==0xd9) &&
          (*(inst_pointer+1)<0xb0) &&  /* need this case of fldz, etc, count */
          ( (*(inst_pointer+1) & 0x38) == 0x28)) {
         result|=FLDCW_INSTRUCTION;
      }
   }

#endif
   return result;
}



   /* Our instrumentation function       */
   /*    sbIn = super block to translate */
   /*    layout = guest layout           */
   /*    gWordTy = size of guest word    */
   /*    hWordTy = size of host word     */
static IRSB* bbv_instrument ( VgCallbackClosure* closure,
                             IRSB* sbIn, VexGuestLayout* layout,
                             VexGuestExtents* vge,
                             VexArchInfo* archinfo_host,
                             IRType gWordTy, IRType hWordTy )
{
   Int      i,n_instrs=1;
   IRSB     *sbOut;
   IRStmt   *st;
   struct BB_info  *bbInfo;
   Addr64   origAddr,ourAddr;
   IRDirty  *di;
   IRExpr   **argv, *arg1;
   Int      regparms,opcode_type;

      /* We don't handle a host/guest word size mismatch */
   if (gWordTy != hWordTy) {
      VG_(tool_panic)("host/guest word size mismatch");
   }

      /* Set up SB */
   sbOut = deepCopyIRSBExceptStmts(sbIn);

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

      /* Get the first statement */
   tl_assert(sbIn->stmts_used > 0);
   st = sbIn->stmts[i];

      /* double check we are at a Mark statement */
   tl_assert(Ist_IMark == st->tag);

   origAddr=st->Ist.IMark.addr;

      /* Get the BB_info */
   bbInfo = VG_(OSetGen_Lookup)(instr_info_table, &origAddr);

   if (bbInfo==NULL) {

         /* BB never translated before (at this address, at least;          */
         /* could have been unloaded and then reloaded elsewhere in memory) */

         /* allocate and initialize a new basic block structure */
      bbInfo=VG_(OSetGen_AllocNode)(instr_info_table, sizeof(struct BB_info));
      bbInfo->BB_addr = origAddr;
      bbInfo->n_instrs = n_instrs;
      bbInfo->inst_counter=VG_(calloc)("bbv_instrument",
                                       allocated_threads,
                                       sizeof(Int));

         /* assign a unique block number */
      bbInfo->block_num=block_num;
      block_num++;
         /* get function name and entry point information */
      VG_(get_fnname)(origAddr,bbInfo->fn_name,FUNCTION_NAME_LENGTH);
      bbInfo->is_entry=VG_(get_fnname_if_entry)(origAddr, bbInfo->fn_name,
                                                FUNCTION_NAME_LENGTH);
         /* insert structure into table */
      VG_(OSetGen_Insert)( instr_info_table, bbInfo );
   }

      /* Iterate through the basic block, putting the original   */
      /* instructions in place, plus putting a call to updateBBV */
      /* for each original instruction                           */

      /* This is less efficient than only instrumenting the BB   */
      /* But it gives proper results given the fact that         */
      /* valgrind uses superblocks (not basic blocks) by default */


   while(i < sbIn->stmts_used) {
      st=sbIn->stmts[i];

      if (st->tag == Ist_IMark) {

         ourAddr = st->Ist.IMark.addr;

         opcode_type=get_inst_type(st->Ist.IMark.len,ourAddr);

         regparms=1;
         arg1= mkIRExpr_HWord( (HWord)bbInfo);
         argv= mkIRExprVec_1(arg1);


         if (opcode_type&REP_INSTRUCTION) {
            arg1= mkIRExpr_HWord(ourAddr);
            argv= mkIRExprVec_1(arg1);
            di= unsafeIRDirty_0_N( regparms, "per_instruction_BBV_rep",
                                VG_(fnptr_to_fnentry)( &per_instruction_BBV_rep ),
                                argv);
         }
         else if (opcode_type&FLDCW_INSTRUCTION) {
            di= unsafeIRDirty_0_N( regparms, "per_instruction_BBV_fldcw",
                                VG_(fnptr_to_fnentry)( &per_instruction_BBV_fldcw ),
                                argv);
         }
         else {
         di= unsafeIRDirty_0_N( regparms, "per_instruction_BBV",
                                VG_(fnptr_to_fnentry)( &per_instruction_BBV ),
                                argv);
         }


            /* Insert our call */
         addStmtToIRSB( sbOut,  IRStmt_Dirty(di));
      }

         /* Insert the original instruction */
      addStmtToIRSB( sbOut, st );

      i++;
   }

   return sbOut;
}

static struct thread_info *allocate_new_thread(struct thread_info *old,
                                     Int old_number, Int new_number)
{
   struct thread_info *temp;
   struct BB_info   *bb_elem;
   Int i;

   temp=VG_(realloc)("bbv_main.c allocate_threads",
                     old,
                     new_number*sizeof(struct thread_info));

      /* init the new thread */
      /* We loop in case the new thread is not contiguous */
   for(i=old_number;i<new_number;i++) {
      temp[i].last_rep_addr=0;
      temp[i].dyn_instr=0;
      temp[i].total_instr=0;
      temp[i].global_rep_count=0;
      temp[i].unique_rep_count=0;
      temp[i].rep_count=0;
      temp[i].fldcw_count=0;
      temp[i].bbtrace_fd=-1;
   }
      /* expand the inst_counter on all allocated basic blocks */
   VG_(OSetGen_ResetIter)(instr_info_table);
   while ( (bb_elem = VG_(OSetGen_Next)(instr_info_table)) ) {
      bb_elem->inst_counter =
                    VG_(realloc)("bbv_main.c inst_counter",
                                 bb_elem->inst_counter,
                                 new_number*sizeof(Int));
      for(i=old_number;i<new_number;i++) {
         bb_elem->inst_counter[i]=0;
      }
   }

   return temp;
}

static void bbv_thread_called ( ThreadId tid, ULong nDisp )
{
   if (tid >= allocated_threads) {
      bbv_thread=allocate_new_thread(bbv_thread,allocated_threads,tid+1);
      allocated_threads=tid+1;
   }
   current_thread=tid;
}




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

static void bbv_post_clo_init(void)
{
   bb_out_file =
          VG_(expand_file_name)("--bb-out-file", clo_bb_out_file);

      /* Try a closer approximation of basic blocks  */
      /* This is the same as the command line option */
      /* --vex-guest-chase-thresh=0                  */
   VG_(clo_vex_control).guest_chase_thresh = 0;
}

   /* Parse the command line options */
static Bool bbv_process_cmd_line_option(const HChar* arg)
{
   if VG_INT_CLO       (arg, "--interval-size",    interval_size) {}
   else if VG_STR_CLO  (arg, "--bb-out-file",      clo_bb_out_file) {}
   else if VG_STR_CLO  (arg, "--pc-out-file",      clo_pc_out_file) {
      generate_pc_file = True;
   }
   else if VG_BOOL_CLO (arg, "--instr-count-only", instr_count_only) {}
   else {
      return False;
   }

   return True;
}

static void bbv_print_usage(void)
{
   VG_(printf)(
"   --bb-out-file=<file>       filename for BBV info\n"
"   --pc-out-file=<file>       filename for BB addresses and function names\n"
"   --interval-size=<num>      interval size\n"
"   --instr-count-only=yes|no  only print total instruction count\n"
   );
}

static void bbv_print_debug_usage(void)
{
   VG_(printf)("    (none)\n");
}

static void bbv_fini(Int exitcode)
{
   Int i;

   if (generate_pc_file) {
      dumpPcFile();
   }

   for(i=0;i<allocated_threads;i++) {

      if (bbv_thread[i].total_instr!=0) {

         VG_(sprintf)(buf,"\n\n"
                          "# Thread %d\n"
                          "#   Total intervals: %d (Interval Size %d)\n"
                          "#   Total instructions: %lld\n"
                          "#   Total reps: %lld\n"
                          "#   Unique reps: %lld\n"
                          "#   Total fldcw instructions: %lld\n\n",
                i,
                (Int)(bbv_thread[i].total_instr/(ULong)interval_size),
                interval_size,
                bbv_thread[i].total_instr,
                bbv_thread[i].global_rep_count,
                bbv_thread[i].unique_rep_count,
                bbv_thread[i].fldcw_count);

            /* Print results to display */
         VG_(umsg)("%s\n", buf);

            /* open the output file if it hasn't already */
         if (bbv_thread[i].bbtrace_fd < 0) {
            bbv_thread[i].bbtrace_fd=open_tracefile(i);
         }
            /* Also print to results file */
         VG_(write)(bbv_thread[i].bbtrace_fd,(void*)buf,VG_(strlen)(buf));
         VG_(close)(bbv_thread[i].bbtrace_fd);
      }
   }
}

static void bbv_pre_clo_init(void)
{
   VG_(details_name)            ("exp-bbv");
   VG_(details_version)         (NULL);
   VG_(details_description)     ("a SimPoint basic block vector generator");
   VG_(details_copyright_author)(
      "Copyright (C) 2006-2013 Vince Weaver");
   VG_(details_bug_reports_to)  (VG_BUGS_TO);

   VG_(basic_tool_funcs)          (bbv_post_clo_init,
                                   bbv_instrument,
                                   bbv_fini);

   VG_(needs_command_line_options)(bbv_process_cmd_line_option,
                                   bbv_print_usage,
                                   bbv_print_debug_usage);

   VG_(track_start_client_code)( bbv_thread_called );


   instr_info_table = VG_(OSetGen_Create)(/*keyOff*/0,
                                          NULL,
                                          VG_(malloc), "bbv.1", VG_(free));

   bbv_thread=allocate_new_thread(bbv_thread,0,allocated_threads);
}

VG_DETERMINE_INTERFACE_VERSION(bbv_pre_clo_init)

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