/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   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 3, 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, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <stdio.h>
#include <string.h>
#include <sys/param.h>

#include "disassemble.h"
#include "dis-asm.h"
#include "demangle.h"
#include "dbe_types.h"
#include "DbeSession.h"
#include "Elf.h"
#include "Disasm.h"
#include "Stabs.h"
#include "i18n.h"
#include "util.h"
#include "StringBuilder.h"
#include "Function.h"

struct DisContext
{
  bool is_Intel;
  Stabs *stabs;
  uint64_t pc;          // first_pc <= pc < last_pc
  uint64_t first_pc;
  uint64_t last_pc;
  uint64_t f_offset;    // file offset for first_pc
  int codeptr[4];       // longest instruction length may not be > 16
  Data_window *elf;
};

static const int MAX_DISASM_STR     = 2048;
static const int MAX_INSTR_SIZE     = 8;

Disasm::Disasm (char *fname)
{
  dwin = NULL;
  dis_str = NULL;
  need_swap_endian = false;
  my_stabs = Stabs::NewStabs (fname, fname);
  if (my_stabs == NULL)
    return;
  stabs = my_stabs;
  platform = stabs->get_platform ();
  disasm_open ();
}

Disasm::Disasm (Platform_t _platform, Stabs *_stabs)
{
  dwin = NULL;
  dis_str = NULL;
  need_swap_endian = false;
  stabs = _stabs;
  platform = _platform;
  my_stabs = NULL;
  disasm_open ();
}

static int
fprintf_func (void *arg, const char *fmt, ...)
{
  char buf[512];
  va_list vp;
  va_start (vp, fmt);
  int cnt = vsnprintf (buf, sizeof (buf), fmt, vp);
  va_end (vp);

  Disasm *dis = (Disasm *) arg;
  dis->dis_str->append (buf);
  return cnt;
}

static int
fprintf_styled_func (void *arg, enum disassembler_style st ATTRIBUTE_UNUSED,
		      const char *fmt, ...)
{
  char buf[512];
  va_list vp;
  va_start (vp, fmt);
  int cnt = vsnprintf (buf, sizeof (buf), fmt, vp);
  va_end (vp);

  Disasm *dis = (Disasm *) arg;
  dis->dis_str->append (buf);
  return cnt;
}

/* Get LENGTH bytes from info's buffer, at target address memaddr.
   Transfer them to myaddr.  */
static int
read_memory_func (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
		  disassemble_info *info)
{
  unsigned int opb = info->octets_per_byte;
  size_t end_addr_offset = length / opb;
  size_t max_addr_offset = info->buffer_length / opb;
  size_t octets = (memaddr - info->buffer_vma) * opb;
  if (memaddr < info->buffer_vma
      || memaddr - info->buffer_vma > max_addr_offset
      || memaddr - info->buffer_vma + end_addr_offset > max_addr_offset
      || (info->stop_vma && (memaddr >= info->stop_vma
			     || memaddr + end_addr_offset > info->stop_vma)))
    return -1;
  memcpy (myaddr, info->buffer + octets, length);
  return 0;
}

static void
print_address_func (bfd_vma addr, disassemble_info *info)
{
  bfd_signed_vma off;
  unsigned long long ta;
  Disasm *dis;
  switch (info->insn_type)
    {
    case dis_branch:
    case dis_condbranch:
      off = (bfd_signed_vma) addr;
      dis = (Disasm *) info->stream;
      ta = dis->inst_addr + off;
      (*info->fprintf_func) (info->stream, ".%c0x%llx [ 0x%llx ]",
		off > 0 ? '+' : '-', (long long) (off > 0 ? off : -off), ta);
      return;
    case dis_jsr:
      off = (bfd_signed_vma) addr;
      dis = (Disasm *) info->stream;
      ta = dis->inst_addr + off;
      const char *nm = NULL;
      Function *f = dis->map_PC_to_func (ta);
      if (f)
	{
	  if (dis->inst_addr >= f->img_offset
	      && dis->inst_addr < f->img_offset + f->size)
	    {	// Same function
	      (*info->fprintf_func) (info->stream, ".%c0x%llx [ 0x%llx ]",
		  off > 0 ? '+' : '-', (long long) (off > 0 ? off : -off), ta);
	      return;
	    }
	  if (f->flags & FUNC_FLAG_PLT)
	    nm = dis->get_funcname_in_plt(ta);
	  if (nm == NULL)
	    nm = f->get_name ();
	}
      if (nm)
	(*info->fprintf_func) (info->stream, "%s [ 0x%llx, .%c0x%llx]",
	    nm, ta, off > 0 ? '+' : '-', (long long) (off > 0 ? off : -off));
      else
	(*info->fprintf_func) (info->stream,
		".%c0x%llx [ 0x%llx ]  // Unable to determine target symbol",
		off > 0 ? '+' : '-', (long long) (off > 0 ? off : -off), ta);
      return;
    }
  (*info->fprintf_func) (info->stream, "0x%llx", (long long) addr);
}

static asymbol *
symbol_at_address_func (bfd_vma addr ATTRIBUTE_UNUSED,
			disassemble_info *info ATTRIBUTE_UNUSED)
{
  return NULL;
}

static bfd_boolean
symbol_is_valid (asymbol * sym ATTRIBUTE_UNUSED,
		 disassemble_info *info ATTRIBUTE_UNUSED)
{
  return TRUE;
}

static void
memory_error_func (int status, bfd_vma addr, disassemble_info *info)
{
  info->fprintf_func (info->stream, "Address 0x%llx is out of bounds.\n",
		      (unsigned long long) addr);
}

void
Disasm::disasm_open ()
{
  hex_visible = 1;
  snprintf (addr_fmt, sizeof (addr_fmt), NTXT ("%s"), NTXT ("%8llx:  "));
  if (dis_str == NULL)
    dis_str = new StringBuilder;

  switch (platform)
    {
    case Aarch64:
    case Intel:
    case Amd64:
      need_swap_endian = (DbeSession::platform == Sparc);
      break;
    case RISCV:
    case Sparcv8plus:
    case Sparcv9:
    case Sparc:
    default:
      need_swap_endian = (DbeSession::platform != Sparc);
      break;
    }

  memset (&dis_info, 0, sizeof (dis_info));
  dis_info.flavour = bfd_target_unknown_flavour;
  dis_info.endian = BFD_ENDIAN_UNKNOWN;
  dis_info.endian_code = dis_info.endian;
  dis_info.octets_per_byte = 1;
  dis_info.disassembler_needs_relocs = FALSE;
  dis_info.fprintf_func = fprintf_func;
  dis_info.fprintf_styled_func = fprintf_styled_func;
  dis_info.stream = this;
  dis_info.disassembler_options = NULL;
  dis_info.read_memory_func = read_memory_func;
  dis_info.memory_error_func = memory_error_func;
  dis_info.print_address_func = print_address_func;
  dis_info.symbol_at_address_func = symbol_at_address_func;
  dis_info.symbol_is_valid = symbol_is_valid;
  dis_info.display_endian = BFD_ENDIAN_UNKNOWN;
  dis_info.symtab = NULL;
  dis_info.symtab_size = 0;
  dis_info.buffer_vma = 0;
  switch (platform)
    {
    case Aarch64:
      dis_info.arch = bfd_arch_aarch64;
      dis_info.mach = bfd_mach_aarch64;
      break;
    case Intel:
    case Amd64:
      dis_info.arch = bfd_arch_i386;
      dis_info.mach = bfd_mach_x86_64;
      break;
    case RISCV:
    case Sparcv8plus:
    case Sparcv9:
    case Sparc:
    default:
      dis_info.arch = bfd_arch_unknown;
      dis_info.endian = BFD_ENDIAN_UNKNOWN;
      break;
    }
  dis_info.display_endian = dis_info.endian = BFD_ENDIAN_BIG;
  dis_info.display_endian = dis_info.endian = BFD_ENDIAN_LITTLE;
  dis_info.display_endian = dis_info.endian = BFD_ENDIAN_UNKNOWN;
  disassemble_init_for_target (&dis_info);
}

Disasm::~Disasm ()
{
  delete my_stabs;
  delete dwin;
  delete dis_str;
}

void
Disasm::set_img_name (char *img_fname)
{
  if (stabs == NULL && img_fname && dwin == NULL)
    {
      dwin = new Data_window (img_fname);
      if (dwin->not_opened ())
	{
	  delete dwin;
	  dwin = NULL;
	  return;
	}
      dwin->need_swap_endian = need_swap_endian;
    }
}

void
Disasm::remove_disasm_hndl (void *hndl)
{
  DisContext *ctx = (DisContext *) hndl;
  delete ctx;
}

void
Disasm::set_addr_end (uint64_t end_address)
{
  char buf[32];
  int len = snprintf (buf, sizeof (buf), "%llx", (long long) end_address);
  snprintf (addr_fmt, sizeof (addr_fmt), "%%%dllx:  ", len < 8 ? 8 : len);
}

char *
Disasm::get_disasm (uint64_t inst_address, uint64_t end_address,
		  uint64_t start_address, uint64_t f_offset, int64_t &inst_size)
{
  inst_size = 0;
  if (inst_address >= end_address)
    return NULL;
  Data_window *dw = stabs ? stabs->openElf (false) : dwin;
  if (dw == NULL)
    return NULL;

  unsigned char buffer[MAX_DISASM_STR];
  dis_info.buffer = buffer;
  dis_info.buffer_length = end_address - inst_address;
  if (dis_info.buffer_length > sizeof (buffer))
    dis_info.buffer_length = sizeof (buffer);
  dw->get_data (f_offset + (inst_address - start_address),
		dis_info.buffer_length, dis_info.buffer);

  dis_str->setLength (0);
  bfd abfd;
  disassembler_ftype disassemble = disassembler (dis_info.arch, dis_info.endian,
						 dis_info.mach, &abfd);
  if (disassemble == NULL)
    {
      printf ("ERROR: unsupported disassemble\n");
      return NULL;
    }
  inst_addr = inst_address;
  inst_size = disassemble (0, &dis_info);
  if (inst_size <= 0)
    {
      inst_size = 0;
      return NULL;
    }
  StringBuilder sb;
  sb.appendf (addr_fmt, inst_address); // Write address

  // Write hex bytes of instruction
  if (hex_visible)
    {
      char bytes[64];
      *bytes = '\0';
      for (int i = 0; i < inst_size; i++)
	{
	  unsigned int hex_value = buffer[i] & 0xff;
	  snprintf (bytes + 3 * i, sizeof (bytes) - 3 * i, "%02x ", hex_value);
	}
      const char *fmt = "%s   ";
      if (platform == Intel)
	fmt = "%-21s   "; // 21 = 3 * 7 - maximum instruction length on Intel
      sb.appendf (fmt, bytes);
    }
  sb.append (dis_str);
  return sb.toString ();
}

Function *
Disasm::map_PC_to_func (uint64_t pc)
{
  uint64_t low_pc = 0;
  if (stabs)
    return stabs->map_PC_to_func (pc, low_pc, NULL);
  return NULL;
}

const char *
Disasm::get_funcname_in_plt (uint64_t pc)
{
  if (stabs)
    {
      Elf *elf = stabs->openElf (true);
      if (elf)
	return elf->get_funcname_in_plt (pc);
    }
  return NULL;
}
