/* Disassembly display.

   Copyright (C) 1998-2026 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 "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-winsource.h"
#include "tui/tui-status.h"
#include "tui/tui-disasm.h"
#include "progspace.h"
#include "objfiles.h"
#include "cli/cli-style.h"
#include "tui/tui-location.h"
#include "gdbsupport/selftest.h"
#include "inferior.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;
	  ++ptr;
	}
    }
  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 = disassembler_styling && gdb_stdout->can_emit_style_escape ();
  string_file gdb_dis_out (term_out);
  struct ui_file *stream = (addr_size == nullptr
			    ? (decltype (stream))&null_stream
			    : (decltype (stream))&gdb_dis_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;

      /* Save the instruction address.  */
      tal.addr = pc;

      try
	{
	  pc += gdb_print_insn (gdbarch, pc, stream, 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;
	}

      /* If that's all we need, continue.  */
      if (addr_size == nullptr)
	{
	  asm_lines.push_back (std::move (tal));
	  continue;
	}

      /* Capture the disassembled instruction.  */
      tal.insn = gdb_dis_out.release ();

      /* And capture the address the instruction is at.  */
      print_address (gdbarch, tal.addr, &gdb_dis_out);
      tal.addr_string = gdb_dis_out.release ();
      tal.addr_size = (term_out
		       ? len_without_escapes (tal.addr_string)
		       : tal.addr_string.size ());

      *addr_size = std::max (*addr_size, tal.addr_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)
{
  bound_minimal_symbol msym_prev;
  bound_minimal_symbol msym
    = lookup_minimal_symbol_by_pc_section (addr - 1, nullptr,
					   lookup_msym_prefer::TEXT,
					   &msym_prev);
  if (msym.minsym != nullptr)
    return msym.value_address ();
  else if (msym_prev.minsym != nullptr)
    return msym_prev.value_address ();

  /* 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 section->addr ();

  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);
      if (asm_lines.empty ())
	return pc;
      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.  */
      std::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);
	  if (asm_lines.empty ())
	    break;
	  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, try to fall
	 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);
	}

      /* The following walk forward assumes that ASM_LINES contains exactly
	 MAX_LINES entries.  */
      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;
      last_addr = asm_lines.back ().addr;
      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;
  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 = tui_location.addr ();

  /* Window size, excluding highlight box.  */
  max_lines = height - box_size ();

  /* 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 gdbarch *gdbarch = get_current_arch ();
  CORE_ADDR addr = 0;

  if (tui_location.addr () == 0)
    {
      if (have_full_symbols (current_program_space)
	  || have_partial_symbols (current_program_space))
	{
	  set_default_source_symtab_and_line ();
	  symtab_and_line sal
	    = get_current_source_symtab_and_line (current_program_space);

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

      if (addr == 0)
	{
	  bound_minimal_symbol main_symbol
	    = lookup_minimal_symbol (current_program_space, main_name ());
	  if (main_symbol.minsym != nullptr)
	    addr = main_symbol.value_address ();
	}
    }
  else				/* The target is executing.  */
    {
      gdbarch = tui_location.gdbarch ();
      addr = tui_location.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 () != nullptr)
    pos = tui_disasm_win ()->height;
  else if (tui_cmd_win () == nullptr)
    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 gdbarch *gdbarch, symtab_and_line sal)
{
  CORE_ADDR low;

  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 (gdbarch, 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 (gdbarch, 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;
}

#if GDB_SELF_TEST
namespace selftests {
namespace tui {
namespace disasm {

static void
run_tests ()
{
  if (current_inferior () != nullptr)
    {
      gdbarch *gdbarch = current_inferior ()->arch ();

      /* Check that tui_find_disassembly_address robustly handles the case of
	 being passed a PC for which gdb_print_insn throws a MEMORY_ERROR.  */
      SELF_CHECK (tui_find_disassembly_address (gdbarch, 0, 1) == 0);
      SELF_CHECK (tui_find_disassembly_address (gdbarch, 0, -1) == 0);
    }
}

} /* namespace disasm */
} /* namespace tui */
} /* namespace selftests */
#endif /* GDB_SELF_TEST */

INIT_GDB_FILE (tui_disasm)
{
#if GDB_SELF_TEST
  selftests::register_test ("tui-disasm", selftests::tui::disasm::run_tests);
#endif
}
