/* 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;

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;
}
