/* Disassembly display.

   Copyright (C) 1998-2020 Free Software Foundation, Inc.

   Contributed by Hewlett-Packard Company.

   This file is part of GDB.

   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 of the License, 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, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "symtab.h"
#include "breakpoint.h"
#include "frame.h"
#include "value.h"
#include "source.h"
#include "disasm.h"
#include "tui/tui.h"
#include "tui/tui-command.h"
#include "tui/tui-data.h"
#include "tui/tui-win.h"
#include "tui/tui-layout.h"
#include "tui/tui-winsource.h"
#include "tui/tui-stack.h"
#include "tui/tui-file.h"
#include "tui/tui-disasm.h"
#include "tui/tui-source.h"
#include "progspace.h"
#include "objfiles.h"
#include "cli/cli-style.h"

#include "gdb_curses.h"

struct tui_asm_line
{
  CORE_ADDR addr;
  std::string addr_string;
  size_t addr_size;
  std::string insn;
};

/* Helper function to find the number of characters in STR, skipping
   any ANSI escape sequences.  */
static size_t
len_without_escapes (const std::string &str)
{
  size_t len = 0;
  const char *ptr = str.c_str ();
  char c;

  while ((c = *ptr++) != '\0')
    {
      if (c == '\033')
	{
	  ui_file_style style;
	  size_t n_read;
	  if (style.parse (ptr, &n_read))
	    ptr += n_read;
	  else
	    {
	      /* Shouldn't happen, but just skip the ESC if it somehow
		 does.  */
	      ++ptr;
	    }
	}
      else
	++len;
    }
  return len;
}

/* Function to disassemble up to COUNT instructions starting from address
   PC into the ASM_LINES vector (which will be emptied of any previous
   contents).  Return the address of the COUNT'th instruction after pc.
   When ADDR_SIZE is non-null then place the maximum size of an address and
   label into the value pointed to by ADDR_SIZE, and set the addr_size
   field on each item in ASM_LINES, otherwise the addr_size fields within
   ASM_LINES are undefined.

   It is worth noting that ASM_LINES might not have COUNT entries when this
   function returns.  If the disassembly is truncated for some other
   reason, for example, we hit invalid memory, then ASM_LINES can have
   fewer entries than requested.  */
static CORE_ADDR
tui_disassemble (struct gdbarch *gdbarch,
		 std::vector<tui_asm_line> &asm_lines,
		 CORE_ADDR pc, int count,
		 size_t *addr_size = nullptr)
{
  bool term_out = source_styling && gdb_stdout->can_emit_style_escape ();
  string_file gdb_dis_out (term_out);

  /* Must start with an empty list.  */
  asm_lines.clear ();

  /* Now construct each line.  */
  for (int i = 0; i < count; ++i)
    {
      tui_asm_line tal;
      CORE_ADDR orig_pc = pc;

      try
	{
	  pc = pc + gdb_print_insn (gdbarch, pc, &gdb_dis_out, NULL);
	}
      catch (const gdb_exception_error &except)
	{
	  /* If PC points to an invalid address then we'll catch a
	     MEMORY_ERROR here, this should stop the disassembly, but
	     otherwise is fine.  */
	  if (except.error != MEMORY_ERROR)
	    throw;
	  return pc;
	}

      /* Capture the disassembled instruction.  */
      tal.insn = std::move (gdb_dis_out.string ());
      gdb_dis_out.clear ();

      /* And capture the address the instruction is at.  */
      tal.addr = orig_pc;
      print_address (gdbarch, orig_pc, &gdb_dis_out);
      tal.addr_string = std::move (gdb_dis_out.string ());
      gdb_dis_out.clear ();

      if (addr_size != nullptr)
	{
	  size_t new_size;

	  if (term_out)
	    new_size = len_without_escapes (tal.addr_string);
	  else
	    new_size = tal.addr_string.size ();
	  *addr_size = std::max (*addr_size, new_size);
	  tal.addr_size = new_size;
	}

      asm_lines.push_back (std::move (tal));
    }
  return pc;
}

/* Look backward from ADDR for an address from which we can start
   disassembling, this needs to be something we can be reasonably
   confident will fall on an instruction boundary.  We use msymbol
   addresses, or the start of a section.  */

static CORE_ADDR
tui_find_backward_disassembly_start_address (CORE_ADDR addr)
{
  struct bound_minimal_symbol msym, msym_prev;

  msym = lookup_minimal_symbol_by_pc_section (addr - 1, nullptr,
					      lookup_msym_prefer::TEXT,
					      &msym_prev);
  if (msym.minsym != nullptr)
    return BMSYMBOL_VALUE_ADDRESS (msym);
  else if (msym_prev.minsym != nullptr)
    return BMSYMBOL_VALUE_ADDRESS (msym_prev);

  /* Find the section that ADDR is in, and look for the start of the
     section.  */
  struct obj_section *section = find_pc_section (addr);
  if (section != NULL)
    return obj_section_addr (section);

  return addr;
}

/* Find the disassembly address that corresponds to FROM lines above
   or below the PC.  Variable sized instructions are taken into
   account by the algorithm.  */
static CORE_ADDR
tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from)
{
  CORE_ADDR new_low;
  int max_lines;

  max_lines = (from > 0) ? from : - from;
  if (max_lines == 0)
    return pc;

  std::vector<tui_asm_line> asm_lines;

  new_low = pc;
  if (from > 0)
    {
      /* Always disassemble 1 extra instruction here, then if the last
	 instruction fails to disassemble we will take the address of the
	 previous instruction that did disassemble as the result.  */
      tui_disassemble (gdbarch, asm_lines, pc, max_lines + 1);
      new_low = asm_lines.back ().addr;
    }
  else
    {
      /* In order to disassemble backwards we need to find a suitable
	 address to start disassembling from and then work forward until we
	 re-find the address we're currently at.  We can then figure out
	 which address will be at the top of the TUI window after our
	 backward scroll.  During our backward disassemble we need to be
	 able to distinguish between the case where the last address we
	 _can_ disassemble is ADDR, and the case where the disassembly
	 just happens to stop at ADDR, for this reason we increase
	 MAX_LINES by one.  */
      max_lines++;

      /* When we disassemble a series of instructions this will hold the
	 address of the last instruction disassembled.  */
      CORE_ADDR last_addr;

      /* And this will hold the address of the next instruction that would
	 have been disassembled.  */
      CORE_ADDR next_addr;

      /* As we search backward if we find an address that looks like a
	 promising starting point then we record it in this structure.  If
	 the next address we try is not a suitable starting point then we
	 will fall back to the address held here.  */
      gdb::optional<CORE_ADDR> possible_new_low;

      /* The previous value of NEW_LOW so we know if the new value is
	 different or not.  */
      CORE_ADDR prev_low;

      do
	{
	  /* Find an address from which we can start disassembling.  */
	  prev_low = new_low;
	  new_low = tui_find_backward_disassembly_start_address (new_low);

	  /* Disassemble forward.  */
	  next_addr = tui_disassemble (gdbarch, asm_lines, new_low, max_lines);
	  last_addr = asm_lines.back ().addr;

	  /* If disassembling from the current value of NEW_LOW reached PC
	     (or went past it) then this would do as a starting point if we
	     can't find anything better, so remember it.  */
	  if (last_addr >= pc && new_low != prev_low
	      && asm_lines.size () >= max_lines)
	    possible_new_low.emplace (new_low);

	  /* Continue searching until we find a value of NEW_LOW from which
	     disassembling MAX_LINES instructions doesn't reach PC.  We
	     know this means we can find the required number of previous
	     instructions then.  */
	}
      while ((last_addr > pc
	      || (last_addr == pc && asm_lines.size () < max_lines))
	     && new_low != prev_low);

      /* If we failed to disassemble the required number of lines then the
	 following walk forward is not going to work, it assumes that
	 ASM_LINES contains exactly MAX_LINES entries.  Instead we should
	 consider falling back to a previous possible start address in
	 POSSIBLE_NEW_LOW.  */
      if (asm_lines.size () < max_lines)
	{
	  if (!possible_new_low.has_value ())
	    return new_low;

	  /* Take the best possible match we have.  */
	  new_low = *possible_new_low;
	  next_addr = tui_disassemble (gdbarch, asm_lines, new_low, max_lines);
	  last_addr = asm_lines.back ().addr;
	  gdb_assert (asm_lines.size () >= max_lines);
	}

      /* Scan forward disassembling one instruction at a time until
	 the last visible instruction of the window matches the pc.
	 We keep the disassembled instructions in the 'lines' window
	 and shift it downward (increasing its addresses).  */
      int pos = max_lines - 1;
      if (last_addr < pc)
	do
	  {
	    pos++;
	    if (pos >= max_lines)
	      pos = 0;

	    CORE_ADDR old_next_addr = next_addr;
	    std::vector<tui_asm_line> single_asm_line;
	    next_addr = tui_disassemble (gdbarch, single_asm_line,
					 next_addr, 1);
	    /* If there are some problems while disassembling exit.  */
	    if (next_addr <= old_next_addr)
	      return pc;
	    gdb_assert (single_asm_line.size () == 1);
	    asm_lines[pos] = single_asm_line[0];
	  } while (next_addr <= pc);
      pos++;
      if (pos >= max_lines)
	 pos = 0;
      new_low = asm_lines[pos].addr;

      /* When scrolling backward the addresses should move backward, or at
	 the very least stay the same if we are at the first address that
	 can be disassembled.  */
      gdb_assert (new_low <= pc);
    }
  return new_low;
}

/* Function to set the disassembly window's content.  */
bool
tui_disasm_window::set_contents (struct gdbarch *arch,
				 const struct symtab_and_line &sal)
{
  int i;
  int max_lines;
  CORE_ADDR cur_pc;
  struct tui_locator_window *locator = tui_locator_win_info_ptr ();
  int tab_len = tui_tab_width;
  int insn_pos;

  CORE_ADDR pc = sal.pc;
  if (pc == 0)
    return false;

  m_gdbarch = arch;
  m_start_line_or_addr.loa = LOA_ADDRESS;
  m_start_line_or_addr.u.addr = pc;
  cur_pc = locator->addr;

  /* Window size, excluding highlight box.  */
  max_lines = height - 2;

  /* Get temporary table that will hold all strings (addr & insn).  */
  std::vector<tui_asm_line> asm_lines;
  size_t addr_size = 0;
  tui_disassemble (m_gdbarch, asm_lines, pc, max_lines, &addr_size);

  /* Align instructions to the same column.  */
  insn_pos = (1 + (addr_size / tab_len)) * tab_len;

  /* Now construct each line.  */
  m_content.resize (max_lines);
  m_max_length = -1;
  for (i = 0; i < max_lines; i++)
    {
      tui_source_element *src = &m_content[i];

      std::string line;
      CORE_ADDR addr;

      if (i < asm_lines.size ())
	{
	  line
	    = (asm_lines[i].addr_string
	       + n_spaces (insn_pos - asm_lines[i].addr_size)
	       + asm_lines[i].insn);
	  addr = asm_lines[i].addr;
	}
      else
	{
	  line = "";
	  addr = 0;
	}

      const char *ptr = line.c_str ();
      int line_len;
      src->line = tui_copy_source_line (&ptr, &line_len);
      m_max_length = std::max (m_max_length, line_len);

      src->line_or_addr.loa = LOA_ADDRESS;
      src->line_or_addr.u.addr = addr;
      src->is_exec_point = (addr == cur_pc && line.size () > 0);
    }
  return true;
}


void
tui_get_begin_asm_address (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
{
  struct tui_locator_window *locator;
  struct gdbarch *gdbarch = get_current_arch ();
  CORE_ADDR addr = 0;

  locator = tui_locator_win_info_ptr ();

  if (locator->addr == 0)
    {
      if (have_full_symbols () || have_partial_symbols ())
	{
	  set_default_source_symtab_and_line ();
	  struct symtab_and_line sal = get_current_source_symtab_and_line ();

	  if (sal.symtab != nullptr)
	    find_line_pc (sal.symtab, sal.line, &addr);
	}

      if (addr == 0)
	{
	  struct bound_minimal_symbol main_symbol
	    = lookup_minimal_symbol (main_name (), nullptr, nullptr);
	  if (main_symbol.minsym != nullptr)
	    addr = BMSYMBOL_VALUE_ADDRESS (main_symbol);
	}
    }
  else				/* The target is executing.  */
    {
      gdbarch = locator->gdbarch;
      addr = locator->addr;
    }

  *gdbarch_p = gdbarch;
  *addr_p = addr;
}

/* Determine what the low address will be to display in the TUI's
   disassembly window.  This may or may not be the same as the low
   address input.  */
CORE_ADDR
tui_get_low_disassembly_address (struct gdbarch *gdbarch,
				 CORE_ADDR low, CORE_ADDR pc)
{
  int pos;

  /* Determine where to start the disassembly so that the pc is about
     in the middle of the viewport.  */
  if (TUI_DISASM_WIN != NULL)
    pos = TUI_DISASM_WIN->height;
  else if (TUI_CMD_WIN == NULL)
    pos = tui_term_height () / 2 - 2;
  else
    pos = tui_term_height () - TUI_CMD_WIN->height - 2;
  pos = (pos - 2) / 2;

  pc = tui_find_disassembly_address (gdbarch, pc, -pos);

  if (pc < low)
    pc = low;
  return pc;
}

/* Scroll the disassembly forward or backward vertically.  */
void
tui_disasm_window::do_scroll_vertical (int num_to_scroll)
{
  if (!m_content.empty ())
    {
      CORE_ADDR pc;

      pc = m_start_line_or_addr.u.addr;

      symtab_and_line sal {};
      sal.pspace = current_program_space;
      sal.pc = tui_find_disassembly_address (m_gdbarch, pc, num_to_scroll);
      update_source_window_as_is (m_gdbarch, sal);
    }
}

bool
tui_disasm_window::location_matches_p (struct bp_location *loc, int line_no)
{
  return (m_content[line_no].line_or_addr.loa == LOA_ADDRESS
	  && m_content[line_no].line_or_addr.u.addr == loc->address);
}

bool
tui_disasm_window::addr_is_displayed (CORE_ADDR addr) const
{
  if (m_content.size () < SCROLL_THRESHOLD)
    return false;

  for (size_t i = 0; i < m_content.size () - SCROLL_THRESHOLD; ++i)
    {
      if (m_content[i].line_or_addr.loa == LOA_ADDRESS
	  && m_content[i].line_or_addr.u.addr == addr)
	return true;
    }

  return false;
}

void
tui_disasm_window::maybe_update (struct frame_info *fi, symtab_and_line sal)
{
  CORE_ADDR low;

  struct gdbarch *frame_arch = get_frame_arch (fi);

  if (find_pc_partial_function (sal.pc, NULL, &low, NULL) == 0)
    {
      /* There is no symbol available for current PC.  There is no
	 safe way how to "disassemble backwards".  */
      low = sal.pc;
    }
  else
    low = tui_get_low_disassembly_address (frame_arch, low, sal.pc);

  struct tui_line_or_address a;

  a.loa = LOA_ADDRESS;
  a.u.addr = low;
  if (!addr_is_displayed (sal.pc))
    {
      sal.pc = low;
      update_source_window (frame_arch, sal);
    }
  else
    {
      a.u.addr = sal.pc;
      set_is_exec_point_at (a);
    }
}

void
tui_disasm_window::display_start_addr (struct gdbarch **gdbarch_p,
				       CORE_ADDR *addr_p)
{
  *gdbarch_p = m_gdbarch;
  *addr_p = m_start_line_or_addr.u.addr;
}
