<commit_before>// $Id$
// -*-C++-*-
// * BeginRiceCopyright *****************************************************
// 
// Copyright ((c)) 2002, Rice University 
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// 
// * Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
// 
// * Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the distribution.
// 
// * Neither the name of Rice University (RICE) nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
// 
// This software is provided by RICE and contributors "as is" and any
// express or implied warranties, including, but not limited to, the
// implied warranties of merchantability and fitness for a particular
// purpose are disclaimed. In no event shall RICE or contributors be
// liable for any direct, indirect, incidental, special, exemplary, or
// consequential damages (including, but not limited to, procurement of
// substitute goods or services; loss of use, data, or profits; or
// business interruption) however caused and on any theory of liability,
// whether in contract, strict liability, or tort (including negligence
// or otherwise) arising in any way out of the use of this software, even
// if advised of the possibility of such damage. 
// 
// ******************************************************* EndRiceCopyright *

//***************************************************************************
//
// File:
//    x86ISA.C
//
// Purpose:
//    [The purpose of this file]
//
// Description:
//    [The set of functions, macros, etc. defined in the file]
//
//***************************************************************************

//************************* System Include Files ****************************

#ifdef NO_STD_CHEADERS
# include <stdarg.h>
# include <string.h>
#else
# include <cstdarg>
# include <cstring> // for 'memcpy'
using namespace std; // For compatibility with non-std C headers
#endif

//*************************** User Include Files ****************************

#include "x86ISA.hpp"
#include <include/gnu_dis-asm.h>

//*************************** Forward Declarations ***************************

//****************************************************************************

extern "C" { 

static int fake_fprintf_func(PTR, const char *fmt, ...)
{
  //va_list ap;
  //va_start(ap, fmt);
  return 0;
}

static void print_addr (bfd_vma vma, struct disassemble_info *info)
{
  info->fprintf_func (info->stream, "0x%08x", vma);
}

static int read_memory_func (bfd_vma vma, bfd_byte *myaddr, unsigned int len,
			     struct disassemble_info *info)
{
  memcpy(myaddr, BFDVMA_TO_PTR(vma, const char*), len);
  return 0; /* success */
}

} // extern "C"

//****************************************************************************
// x86ISA
//****************************************************************************

x86ISA::x86ISA(bool is_x86_64)
  : mIs_x86_64(is_x86_64), di(NULL)
{
  // See 'dis-asm.h'
  di = new disassemble_info;
  INIT_DISASSEMBLE_INFO(*di, stdout, fake_fprintf_func);
  //  fprintf_func: (int (*)(void *, const char *, ...))fprintf;

  di->arch = bfd_arch_i386;      // bfd_get_arch(abfd);
  if (mIs_x86_64) {              // bfd_get_mach(abfd); needed in print_insn()
    di->mach = bfd_mach_x86_64;
  }
  else {
    di->mach = bfd_mach_i386_i386; 
  }
  di->endian = BFD_ENDIAN_LITTLE;
  di->read_memory_func = read_memory_func; // vs. 'buffer_read_memory'
  di->print_address_func = print_addr;     // vs. 'generic_print_address'
}

x86ISA::~x86ISA()
{
  delete di;
}

ushort
x86ISA::GetInstSize(MachInst* mi)
{
  ushort size;
  DecodingCache *cache;

  if ((cache = CacheLookup(mi)) == NULL) {
    size = print_insn_i386(PTR_TO_BFDVMA(mi), di);
    CacheSet(mi, size);
  } else {
    size = cache->instSize;
  }
  return size;
}

ISA::InstDesc
x86ISA::GetInstDesc(MachInst* mi, ushort opIndex, ushort s)
{
  ISA::InstDesc d;

  if (CacheLookup(mi) == NULL) {
    ushort size = print_insn_i386(PTR_TO_BFDVMA(mi), di);
    CacheSet(mi, size);
  }

  switch(di->insn_type) {
    case dis_noninsn:
      d.Set(InstDesc::INVALID);
      break;
    case dis_branch:
      if (di->target != 0) {
	d.Set(InstDesc::BR_UN_COND_REL);
      } else {
	d.Set(InstDesc::BR_UN_COND_IND);
      }
      break;
    case dis_condbranch:
      if (di->target != 0) {
	d.Set(InstDesc::INT_BR_COND_REL); // arbitrarily choose int
      } else {
	d.Set(InstDesc::INT_BR_COND_IND); // arbitrarily choose int
      }
      break;
    case dis_jsr:
      if (di->target != 0) {
	d.Set(InstDesc::SUBR_REL);
      } else {
	d.Set(InstDesc::SUBR_IND);
      }
      break;
    case dis_condjsr:
      d.Set(InstDesc::OTHER);
      break;
    case dis_return:
      d.Set(InstDesc::SUBR_RET);
      break;
    case dis_dref:
    case dis_dref2:
      d.Set(InstDesc::MEM_OTHER);
      break;
    default:
      d.Set(InstDesc::OTHER);
      break;
  }
  return d;
}

Addr
x86ISA::GetInstTargetAddr(MachInst* mi, Addr pc, ushort opIndex, ushort sz)
{
  static bfd_vma mask32 = (bfd_vma)0x0 | 0xffffffff;
  
  if (CacheLookup(mi) == NULL) {
    ushort size = print_insn_i386(PTR_TO_BFDVMA(mi), di);
    CacheSet(mi, size);
  }

  // N.B.: The GNU decoders expect that the address of the 'mi' is
  // actually the PC/vma.  Furthermore for 32-bit x86 decoding, only
  // the lower 32 bits of 'mi' are valid.
  
  // The target field is only set on instructions with targets.
  if (di->target != 0) {
    Addr tgt = (mIs_x86_64) ?
      ((di->target & mask32) - PTR_TO_BFDVMA(mi)) + (bfd_vma)pc :
      (di->target - (PTR_TO_BFDVMA(mi) & mask32)) + (bfd_vma)pc;
    return tgt;
  } 
  else {
    return 0;
  }
}


<commit_msg>Clean up GetInstTargetAddr()<commit_after>// $Id$
// -*-C++-*-
// * BeginRiceCopyright *****************************************************
// 
// Copyright ((c)) 2002, Rice University 
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// 
// * Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
// 
// * Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the distribution.
// 
// * Neither the name of Rice University (RICE) nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
// 
// This software is provided by RICE and contributors "as is" and any
// express or implied warranties, including, but not limited to, the
// implied warranties of merchantability and fitness for a particular
// purpose are disclaimed. In no event shall RICE or contributors be
// liable for any direct, indirect, incidental, special, exemplary, or
// consequential damages (including, but not limited to, procurement of
// substitute goods or services; loss of use, data, or profits; or
// business interruption) however caused and on any theory of liability,
// whether in contract, strict liability, or tort (including negligence
// or otherwise) arising in any way out of the use of this software, even
// if advised of the possibility of such damage. 
// 
// ******************************************************* EndRiceCopyright *

//***************************************************************************
//
// File:
//    x86ISA.C
//
// Purpose:
//    [The purpose of this file]
//
// Description:
//    [The set of functions, macros, etc. defined in the file]
//
//***************************************************************************

//************************* System Include Files ****************************

#ifdef NO_STD_CHEADERS
# include <stdarg.h>
# include <string.h>
#else
# include <cstdarg>
# include <cstring> // for 'memcpy'
using namespace std; // For compatibility with non-std C headers
#endif

//*************************** User Include Files ****************************

#include "x86ISA.hpp"
#include <include/gnu_dis-asm.h>

//*************************** Forward Declarations ***************************

//****************************************************************************

extern "C" { 

static int fake_fprintf_func(PTR, const char *fmt, ...)
{
  //va_list ap;
  //va_start(ap, fmt);
  return 0;
}

static void print_addr (bfd_vma vma, struct disassemble_info *info)
{
  info->fprintf_func (info->stream, "0x%08x", vma);
}

static int read_memory_func (bfd_vma vma, bfd_byte *myaddr, unsigned int len,
			     struct disassemble_info *info)
{
  memcpy(myaddr, BFDVMA_TO_PTR(vma, const char*), len);
  return 0; /* success */
}

} // extern "C"

//****************************************************************************
// x86ISA
//****************************************************************************

x86ISA::x86ISA(bool is_x86_64)
  : mIs_x86_64(is_x86_64), di(NULL)
{
  // See 'dis-asm.h'
  di = new disassemble_info;
  INIT_DISASSEMBLE_INFO(*di, stdout, fake_fprintf_func);
  //  fprintf_func: (int (*)(void *, const char *, ...))fprintf;

  di->arch = bfd_arch_i386;      // bfd_get_arch(abfd);
  if (mIs_x86_64) {              // bfd_get_mach(abfd); needed in print_insn()
    di->mach = bfd_mach_x86_64;
  }
  else {
    di->mach = bfd_mach_i386_i386;
  }
  di->endian = BFD_ENDIAN_LITTLE;
  di->read_memory_func = read_memory_func; // vs. 'buffer_read_memory'
  di->print_address_func = print_addr;     // vs. 'generic_print_address'
}

x86ISA::~x86ISA()
{
  delete di;
}

ushort
x86ISA::GetInstSize(MachInst* mi)
{
  ushort size;
  DecodingCache *cache;

  if ((cache = CacheLookup(mi)) == NULL) {
    size = print_insn_i386(PTR_TO_BFDVMA(mi), di);
    CacheSet(mi, size);
  } else {
    size = cache->instSize;
  }
  return size;
}

ISA::InstDesc
x86ISA::GetInstDesc(MachInst* mi, ushort opIndex, ushort s)
{
  ISA::InstDesc d;

  if (CacheLookup(mi) == NULL) {
    ushort size = print_insn_i386(PTR_TO_BFDVMA(mi), di);
    CacheSet(mi, size);
  }

  switch(di->insn_type) {
    case dis_noninsn:
      d.Set(InstDesc::INVALID);
      break;
    case dis_branch:
      if (di->target != 0) {
	d.Set(InstDesc::BR_UN_COND_REL);
      } else {
	d.Set(InstDesc::BR_UN_COND_IND);
      }
      break;
    case dis_condbranch:
      if (di->target != 0) {
	d.Set(InstDesc::INT_BR_COND_REL); // arbitrarily choose int
      } else {
	d.Set(InstDesc::INT_BR_COND_IND); // arbitrarily choose int
      }
      break;
    case dis_jsr:
      if (di->target != 0) {
	d.Set(InstDesc::SUBR_REL);
      } else {
	d.Set(InstDesc::SUBR_IND);
      }
      break;
    case dis_condjsr:
      d.Set(InstDesc::OTHER);
      break;
    case dis_return:
      d.Set(InstDesc::SUBR_RET);
      break;
    case dis_dref:
    case dis_dref2:
      d.Set(InstDesc::MEM_OTHER);
      break;
    default:
      d.Set(InstDesc::OTHER);
      break;
  }
  return d;
}

Addr
x86ISA::GetInstTargetAddr(MachInst* mi, Addr pc, ushort opIndex, ushort sz)
{
  static const bfd_vma mask32 = 0xffffffff;
  
  if (CacheLookup(mi) == NULL) {
    ushort size = print_insn_i386(PTR_TO_BFDVMA(mi), di);
    CacheSet(mi, size);
  }

  // N.B.: The GNU decoders expect that the address of the 'mi' is
  // actually the PC/vma.  Furthermore for 32-bit x86 decoding, only
  // the lower 32 bits of 'mi' are valid.
  
  // The target field is only set on instructions with targets.
  if (di->target != 0) {
    Addr tgt = (mIs_x86_64) ?
      ((di->target & mask32) - PTR_TO_BFDVMA(mi)) + (bfd_vma)pc :
      (di->target - (PTR_TO_BFDVMA(mi) & mask32)) + (bfd_vma)pc;
    return tgt;
  } 
  else {
    return 0;
  }
}



{'fraction_non_alphanumeric': 0.2183832581042265, 'fraction_numerical': 0.014936397209684038, 'mean_word_length': 3.5521105715353007, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7520947', 'n_tokens_mistral': 4131, 'n_tokens_neox': 3899, 'n_words': 1098}