/* Opcode printing code for the WebAssembly target
   Copyright (C) 2017-2020 Free Software Foundation, Inc.

   This file is part of libopcodes.

   This library 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 of the License, or
   (at your option) any later version.

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

#include "sysdep.h"
#include "disassemble.h"
#include "opintl.h"
#include "safe-ctype.h"
#include "floatformat.h"
#include "libiberty.h"
#include "elf-bfd.h"
#include "elf/internal.h"
#include "elf/wasm32.h"
#include "bfd_stdint.h"

/* Type names for blocks and signatures.  */
#define BLOCK_TYPE_NONE              0x40
#define BLOCK_TYPE_I32               0x7f
#define BLOCK_TYPE_I64               0x7e
#define BLOCK_TYPE_F32               0x7d
#define BLOCK_TYPE_F64               0x7c

enum wasm_class
{
  wasm_typed,
  wasm_special,
  wasm_break,
  wasm_break_if,
  wasm_break_table,
  wasm_return,
  wasm_call,
  wasm_call_import,
  wasm_call_indirect,
  wasm_get_local,
  wasm_set_local,
  wasm_tee_local,
  wasm_drop,
  wasm_constant_i32,
  wasm_constant_i64,
  wasm_constant_f32,
  wasm_constant_f64,
  wasm_unary,
  wasm_binary,
  wasm_conv,
  wasm_load,
  wasm_store,
  wasm_select,
  wasm_relational,
  wasm_eqz,
  wasm_current_memory,
  wasm_grow_memory,
  wasm_signature
};

struct wasm32_private_data
{
  bfd_boolean print_registers;
  bfd_boolean print_well_known_globals;

  /* Limit valid symbols to those with a given prefix.  */
  const char *section_prefix;
};

typedef struct
{
  const char *name;
  const char *description;
} wasm32_options_t;

static const wasm32_options_t options[] =
{
  { "registers", N_("Disassemble \"register\" names") },
  { "globals",   N_("Name well-known globals") },
};

#define WASM_OPCODE(opcode, name, intype, outtype, clas, signedness)     \
  { name, wasm_ ## clas, opcode },

struct wasm32_opcode_s
{
  const char *name;
  enum wasm_class clas;
  unsigned char opcode;
} wasm32_opcodes[] =
{
#include "opcode/wasm.h"
  { NULL, 0, 0 }
};

/* Parse the disassembler options in OPTS and initialize INFO.  */

static void
parse_wasm32_disassembler_options (struct disassemble_info *info,
                                   const char *opts)
{
  struct wasm32_private_data *private = info->private_data;

  while (opts != NULL)
    {
      if (CONST_STRNEQ (opts, "registers"))
        private->print_registers = TRUE;
      else if (CONST_STRNEQ (opts, "globals"))
        private->print_well_known_globals = TRUE;

      opts = strchr (opts, ',');
      if (opts)
        opts++;
    }
}

/* Check whether SYM is valid.  Special-case absolute symbols, which
   are unhelpful to print, and arguments to a "call" insn, which we
   want to be in a section matching a given prefix.  */

static bfd_boolean
wasm32_symbol_is_valid (asymbol *sym,
                        struct disassemble_info *info)
{
  struct wasm32_private_data *private_data = info->private_data;

  if (sym == NULL)
    return FALSE;

  if (strcmp(sym->section->name, "*ABS*") == 0)
    return FALSE;

  if (private_data && private_data->section_prefix != NULL
      && strncmp (sym->section->name, private_data->section_prefix,
                  strlen (private_data->section_prefix)))
    return FALSE;

  return TRUE;
}

/* Initialize the disassembler structures for INFO.  */

void
disassemble_init_wasm32 (struct disassemble_info *info)
{
  if (info->private_data == NULL)
    {
      static struct wasm32_private_data private;

      private.print_registers = FALSE;
      private.print_well_known_globals = FALSE;
      private.section_prefix = NULL;

      info->private_data = &private;
    }

  if (info->disassembler_options)
    {
      parse_wasm32_disassembler_options (info, info->disassembler_options);

      info->disassembler_options = NULL;
    }

  info->symbol_is_valid = wasm32_symbol_is_valid;
}

/* Read an LEB128-encoded integer from INFO at address PC, reading one
   byte at a time.  Set ERROR_RETURN if no complete integer could be
   read, LENGTH_RETURN to the number oof bytes read (including bytes
   in incomplete numbers).  SIGN means interpret the number as
   SLEB128.  Unfortunately, this is a duplicate of wasm-module.c's
   wasm_read_leb128 ().  */

static uint64_t
wasm_read_leb128 (bfd_vma                   pc,
                  struct disassemble_info * info,
                  bfd_boolean *             error_return,
                  unsigned int *            length_return,
                  bfd_boolean               sign)
{
  uint64_t result = 0;
  unsigned int num_read = 0;
  unsigned int shift = 0;
  unsigned char byte = 0;
  int status = 1;

  while (info->read_memory_func (pc + num_read, &byte, 1, info) == 0)
    {
      num_read++;

      if (shift < sizeof (result) * 8)
	{
	  result |= ((uint64_t) (byte & 0x7f)) << shift;
	  if ((result >> shift) != (byte & 0x7f))
	    /* Overflow.  */
	    status |= 2;
	  shift += 7;
	}
      else if ((byte & 0x7f) != 0)
	status |= 2;

      if ((byte & 0x80) == 0)
	{
	  status &= ~1;
	  if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
	    result |= -((uint64_t) 1 << shift);
	  break;
	}
    }

  if (length_return != NULL)
    *length_return = num_read;
  if (error_return != NULL)
    *error_return = status != 0;

  return result;
}

/* Read a 32-bit IEEE float from PC using INFO, convert it to a host
   double, and store it at VALUE.  */

static int
read_f32 (double *value, bfd_vma pc, struct disassemble_info *info)
{
  bfd_byte buf[4];

  if (info->read_memory_func (pc, buf, sizeof (buf), info))
    return -1;

  floatformat_to_double (&floatformat_ieee_single_little, buf,
                         value);

  return sizeof (buf);
}

/* Read a 64-bit IEEE float from PC using INFO, convert it to a host
   double, and store it at VALUE.  */

static int
read_f64 (double *value, bfd_vma pc, struct disassemble_info *info)
{
  bfd_byte buf[8];

  if (info->read_memory_func (pc, buf, sizeof (buf), info))
    return -1;

  floatformat_to_double (&floatformat_ieee_double_little, buf,
                         value);

  return sizeof (buf);
}

/* Main disassembly routine.  Disassemble insn at PC using INFO.  */

int
print_insn_wasm32 (bfd_vma pc, struct disassemble_info *info)
{
  unsigned char opcode;
  struct wasm32_opcode_s *op;
  bfd_byte buffer[16];
  void *stream = info->stream;
  fprintf_ftype prin = info->fprintf_func;
  struct wasm32_private_data *private_data = info->private_data;
  uint64_t val;
  int len;
  unsigned int bytes_read;
  bfd_boolean error;

  if (info->read_memory_func (pc, buffer, 1, info))
    return -1;

  opcode = buffer[0];

  for (op = wasm32_opcodes; op->name; op++)
    if (op->opcode == opcode)
      break;

  if (!op->name)
    {
      prin (stream, "\t.byte 0x%02x\n", buffer[0]);
      return 1;
    }

  len = 1;

  prin (stream, "\t");
  prin (stream, "%s", op->name);

  if (op->clas == wasm_typed)
    {
      val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, FALSE);
      if (error)
	return -1;
      len += bytes_read;
      switch (val)
	{
	case BLOCK_TYPE_NONE:
	  prin (stream, "[]");
	  break;
	case BLOCK_TYPE_I32:
	  prin (stream, "[i]");
	  break;
	case BLOCK_TYPE_I64:
	  prin (stream, "[l]");
	  break;
	case BLOCK_TYPE_F32:
	  prin (stream, "[f]");
	  break;
	case BLOCK_TYPE_F64:
	  prin (stream, "[d]");
	  break;
	default:
	  return -1;
	}
    }

  switch (op->clas)
    {
    case wasm_special:
    case wasm_eqz:
    case wasm_binary:
    case wasm_unary:
    case wasm_conv:
    case wasm_relational:
    case wasm_drop:
    case wasm_signature:
    case wasm_call_import:
    case wasm_typed:
    case wasm_select:
      break;

    case wasm_break_table:
      {
	uint32_t target_count, i;
	val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				FALSE);
	target_count = val;
	if (error || target_count != val || target_count == (uint32_t) -1)
	  return -1;
	len += bytes_read;
	prin (stream, " %u", target_count);
	for (i = 0; i < target_count + 1; i++)
	  {
	    uint32_t target;
	    val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				    FALSE);
	    target = val;
	    if (error || target != val)
	      return -1;
	    len += bytes_read;
	    prin (stream, " %u", target);
	  }
      }
      break;

    case wasm_break:
    case wasm_break_if:
      {
	uint32_t depth;
	val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				FALSE);
	depth = val;
	if (error || depth != val)
	  return -1;
	len += bytes_read;
	prin (stream, " %u", depth);
      }
      break;

    case wasm_return:
      break;

    case wasm_constant_i32:
    case wasm_constant_i64:
      val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, TRUE);
      if (error)
	return -1;
      len += bytes_read;
      prin (stream, " %" PRId64, val);
      break;

    case wasm_constant_f32:
      {
	double fconstant;
	int ret;
	/* This appears to be the best we can do, even though we're
	   using host doubles for WebAssembly floats.  */
	ret = read_f32 (&fconstant, pc + len, info);
	if (ret < 0)
	  return -1;
	len += ret;
	prin (stream, " %.9g", fconstant);
      }
      break;

    case wasm_constant_f64:
      {
	double fconstant;
	int ret;
	ret = read_f64 (&fconstant, pc + len, info);
	if (ret < 0)
	  return -1;
	len += ret;
	prin (stream, " %.17g", fconstant);
      }
      break;

    case wasm_call:
      {
	uint32_t function_index;
	val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				FALSE);
	function_index = val;
	if (error || function_index != val)
	  return -1;
	len += bytes_read;
	prin (stream, " ");
	private_data->section_prefix = ".space.function_index";
	(*info->print_address_func) ((bfd_vma) function_index, info);
	private_data->section_prefix = NULL;
      }
      break;

    case wasm_call_indirect:
      {
	uint32_t type_index, xtra_index;
	val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				FALSE);
	type_index = val;
	if (error || type_index != val)
	  return -1;
	len += bytes_read;
	prin (stream, " %u", type_index);
	val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				FALSE);
	xtra_index = val;
	if (error || xtra_index != val)
	  return -1;
	len += bytes_read;
	prin (stream, " %u", xtra_index);
      }
      break;

    case wasm_get_local:
    case wasm_set_local:
    case wasm_tee_local:
      {
	uint32_t local_index;
	val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				FALSE);
	local_index = val;
	if (error || local_index != val)
	  return -1;
	len += bytes_read;
	prin (stream, " %u", local_index);
	if (strcmp (op->name + 4, "local") == 0)
	  {
	    static const char *locals[] =
	      {
		"$dpc", "$sp1", "$r0", "$r1", "$rpc", "$pc0",
		"$rp", "$fp", "$sp",
		"$r2", "$r3", "$r4", "$r5", "$r6", "$r7",
		"$i0", "$i1", "$i2", "$i3", "$i4", "$i5", "$i6", "$i7",
		"$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
	      };
	    if (private_data->print_registers
		&& local_index < ARRAY_SIZE (locals))
	      prin (stream, " <%s>", locals[local_index]);
	  }
	else
	  {
	    static const char *globals[] =
	      {
		"$got", "$plt", "$gpo"
	      };
	    if (private_data->print_well_known_globals
		&& local_index < ARRAY_SIZE (globals))
	      prin (stream, " <%s>", globals[local_index]);
	  }
      }
      break;

    case wasm_grow_memory:
    case wasm_current_memory:
      {
	uint32_t reserved_size;
	val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				FALSE);
	reserved_size = val;
	if (error || reserved_size != val)
	  return -1;
	len += bytes_read;
	prin (stream, " %u", reserved_size);
      }
      break;

    case wasm_load:
    case wasm_store:
      {
	uint32_t flags, offset;
	val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				FALSE);
	flags = val;
	if (error || flags != val)
	  return -1;
	len += bytes_read;
	val = wasm_read_leb128 (pc + len, info, &error, &bytes_read,
				FALSE);
	offset = val;
	if (error || offset != val)
	  return -1;
	len += bytes_read;
	prin (stream, " a=%u %u", flags, offset);
      }
      break;
    }
  return len;
}

/* Print valid disassembler options to STREAM.  */

void
print_wasm32_disassembler_options (FILE *stream)
{
  unsigned int i, max_len = 0;

  fprintf (stream, _("\
The following WebAssembly-specific disassembler options are supported for use\n\
with the -M switch:\n"));

  for (i = 0; i < ARRAY_SIZE (options); i++)
    {
      unsigned int len = strlen (options[i].name);

      if (max_len < len)
	max_len = len;
    }

  for (i = 0, max_len++; i < ARRAY_SIZE (options); i++)
    fprintf (stream, "  %s%*c %s\n",
	     options[i].name,
	     (int)(max_len - strlen (options[i].name)), ' ',
	     _(options[i].description));
}
