/* Copyright (C) 2021-2026 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 (Platform_t _platform, Stabs *_stabs)
{
  dwin = NULL;
  dis_str = NULL;
  need_swap_endian = false;
  stabs = _stabs;
  platform = _platform;
  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 bool
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 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 (false);
      if (elf)
	return elf->get_funcname_in_plt (pc);
    }
  return NULL;
}
