/* Block-related functions for the GNU debugger, GDB.

   Copyright (C) 2003-2024 Free Software Foundation, Inc.

   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 "block.h"
#include "symtab.h"
#include "symfile.h"
#include "gdbsupport/gdb_obstack.h"
#include "cp-support.h"
#include "addrmap.h"
#include "gdbtypes.h"
#include "objfiles.h"
#include "cli/cli-cmds.h"
#include "inferior.h"

/* This is used by struct block to store namespace-related info for
   C++ files, namely using declarations and the current namespace in
   scope.  */

struct block_namespace_info : public allocate_on_obstack<block_namespace_info>
{
  const char *scope = nullptr;
  struct using_direct *using_decl = nullptr;
};

/* See block.h.  */

struct objfile *
block::objfile () const
{
  if (function () != nullptr)
    return function ()->objfile ();

  return this->global_block ()->compunit ()->objfile ();
}

/* See block.  */

struct gdbarch *
block::gdbarch () const
{
  if (function () != nullptr)
    return function ()->arch ();

  return objfile ()->arch ();
}

/* See block.h.  */

bool
block::contains (const struct block *a, bool allow_nested) const
{
  if (a == nullptr)
    return false;

  do
    {
      if (a == this)
	return true;
      /* If A is a function block, then A cannot be contained in B,
	 except if A was inlined.  */
      if (!allow_nested && a->function () != NULL && !a->inlined_p ())
	return false;
      a = a->superblock ();
    }
  while (a != NULL);

  return false;
}

/* See block.h.  */

struct symbol *
block::linkage_function () const
{
  const block *bl = this;

  while ((bl->function () == NULL || bl->inlined_p ())
	 && bl->superblock () != NULL)
    bl = bl->superblock ();

  return bl->function ();
}

/* See block.h.  */

struct symbol *
block::containing_function () const
{
  const block *bl = this;

  while (bl->function () == NULL && bl->superblock () != NULL)
    bl = bl->superblock ();

  return bl->function ();
}

/* See block.h.  */

bool
block::inlined_p () const
{
  return function () != nullptr && function ()->is_inlined ();
}

/* A helper function that checks whether PC is in the blockvector BL.
   It returns the containing block if there is one, or else NULL.  */

static const struct block *
find_block_in_blockvector (const struct blockvector *bl, CORE_ADDR pc)
{
  const struct block *b;
  int bot, top, half;

  /* If we have an addrmap mapping code addresses to blocks, then use
     that.  */
  if (bl->map ())
    return (const struct block *) bl->map ()->find (pc);

  /* Otherwise, use binary search to find the last block that starts
     before PC.
     Note: GLOBAL_BLOCK is block 0, STATIC_BLOCK is block 1.
     They both have the same START,END values.
     Historically this code would choose STATIC_BLOCK over GLOBAL_BLOCK but the
     fact that this choice was made was subtle, now we make it explicit.  */
  gdb_assert (bl->blocks ().size () >= 2);
  bot = STATIC_BLOCK;
  top = bl->blocks ().size ();

  while (top - bot > 1)
    {
      half = (top - bot + 1) >> 1;
      b = bl->block (bot + half);
      if (b->start () <= pc)
	bot += half;
      else
	top = bot + half;
    }

  /* Now search backward for a block that ends after PC.  */

  while (bot >= STATIC_BLOCK)
    {
      b = bl->block (bot);
      if (!(b->start () <= pc))
	return NULL;
      if (b->end () > pc)
	return b;
      bot--;
    }

  return NULL;
}

/* Return the blockvector immediately containing the innermost lexical
   block containing the specified pc value and section, or 0 if there
   is none.  PBLOCK is a pointer to the block.  If PBLOCK is NULL, we
   don't pass this information back to the caller.  */

const struct blockvector *
blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
			 const struct block **pblock,
			 struct compunit_symtab *cust)
{
  const struct blockvector *bl;
  const struct block *b;

  if (cust == NULL)
    {
      /* First search all symtabs for one whose file contains our pc */
      cust = find_pc_sect_compunit_symtab (pc, section);
      if (cust == NULL)
	return 0;
    }

  bl = cust->blockvector ();

  /* Then search that symtab for the smallest block that wins.  */
  b = find_block_in_blockvector (bl, pc);
  if (b == NULL)
    return NULL;

  if (pblock)
    *pblock = b;
  return bl;
}

/* Return true if the blockvector BV contains PC, false otherwise.  */

int
blockvector_contains_pc (const struct blockvector *bv, CORE_ADDR pc)
{
  return find_block_in_blockvector (bv, pc) != NULL;
}

/* Return call_site for specified PC in GDBARCH.  PC must match exactly, it
   must be the next instruction after call (or after tail call jump).  Throw
   NO_ENTRY_VALUE_ERROR otherwise.  This function never returns NULL.  */

struct call_site *
call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  struct compunit_symtab *cust;
  call_site *cs = nullptr;

  /* -1 as tail call PC can be already after the compilation unit range.  */
  cust = find_pc_compunit_symtab (pc - 1);

  if (cust != nullptr)
    cs = cust->find_call_site (pc);

  if (cs == nullptr)
    {
      bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc);

      /* DW_TAG_gnu_call_site will be missing just if GCC could not determine
	 the call target.  */
      throw_error (NO_ENTRY_VALUE_ERROR,
		   _("DW_OP_entry_value resolving cannot find "
		     "DW_TAG_call_site %s in %s"),
		   paddress (gdbarch, pc),
		   (msym.minsym == NULL ? "???"
		    : msym.minsym->print_name ()));
    }

  return cs;
}

/* Return the blockvector immediately containing the innermost lexical block
   containing the specified pc value, or 0 if there is none.
   Backward compatibility, no section.  */

const struct blockvector *
blockvector_for_pc (CORE_ADDR pc, const struct block **pblock)
{
  return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
				  pblock, NULL);
}

/* Return the innermost lexical block containing the specified pc value
   in the specified section, or 0 if there is none.  */

const struct block *
block_for_pc_sect (CORE_ADDR pc, struct obj_section *section)
{
  const struct blockvector *bl;
  const struct block *b;

  bl = blockvector_for_pc_sect (pc, section, &b, NULL);
  if (bl)
    return b;
  return 0;
}

/* Return the innermost lexical block containing the specified pc value,
   or 0 if there is none.  Backward compatibility, no section.  */

const struct block *
block_for_pc (CORE_ADDR pc)
{
  return block_for_pc_sect (pc, find_pc_mapped_section (pc));
}

/* Now come some functions designed to deal with C++ namespace issues.
   The accessors are safe to use even in the non-C++ case.  */

/* See block.h.  */

const char *
block::scope () const
{
  for (const block *block = this;
       block != nullptr;
       block = block->superblock ())
    {
      if (block->m_namespace_info != nullptr
	  && block->m_namespace_info->scope != nullptr)
	return block->m_namespace_info->scope;
    }

  return "";
}

/* See block.h.  */

void
block::initialize_namespace (struct obstack *obstack)
{
  if (m_namespace_info == nullptr)
    m_namespace_info = new (obstack) struct block_namespace_info;
}

/* See block.h.  */

void
block::set_scope (const char *scope, struct obstack *obstack)
{
  if (scope == nullptr || scope[0] == '\0')
    {
      /* Don't bother.  */
      return;
    }

  initialize_namespace (obstack);
  m_namespace_info->scope = scope;
}

/* See block.h.  */

next_range<using_direct>
block::get_using () const
{
  if (m_namespace_info == nullptr)
    return {};
  else
    return next_range<using_direct> (m_namespace_info->using_decl);
}

/* See block.h.  */

void
block::set_using (struct using_direct *using_decl, struct obstack *obstack)
{
  if (using_decl == nullptr)
    {
      /* Don't bother.  */
      return;
    }

  initialize_namespace (obstack);
  m_namespace_info->using_decl = using_decl;
}

/* See block.h.  */

const struct block *
block::static_block () const
{
  if (superblock () == nullptr)
    return nullptr;

  const block *block = this;
  while (block->superblock ()->superblock () != NULL)
    block = block->superblock ();

  return block;
}

/* See block.h.  */

const struct global_block *
block::global_block () const
{
  const block *block = this;

  while (block->superblock () != NULL)
    block = block->superblock ();

  return block->as_global_block ();
}

/* See block.h.  */

struct global_block *
block::as_global_block ()
{
  gdb_assert (this->is_global_block ());

  return static_cast<struct global_block *>(this);
}

/* See block.h.  */

const struct global_block *
block::as_global_block () const
{
  gdb_assert (this->is_global_block ());

  return static_cast<const struct global_block *>(this);
}

/* See block.h.  */

const struct block *
block::function_block () const
{
  const block *block = this;

  while (block != nullptr && block->function () == nullptr)
    block = block->superblock ();

  return block;
}

/* See block.h.  */

struct dynamic_prop *
block::static_link () const
{
  struct objfile *objfile = this->objfile ();

  /* Only objfile-owned blocks that materialize top function scopes can have
     static links.  */
  if (objfile == NULL || function () == NULL)
    return NULL;

  return (struct dynamic_prop *) objfile_lookup_static_link (objfile, this);
}

/* Initialize a block iterator, either to iterate over a single block,
   or, for static and global blocks, all the included symtabs as
   well.  */

static void
initialize_block_iterator (const struct block *block,
			   struct block_iterator *iter,
			   const lookup_name_info *name)
{
  enum block_enum which;

  iter->idx = -1;
  iter->name = name;

  if (block->is_global_block ())
    which = GLOBAL_BLOCK;
  else if (block->is_static_block ())
    which = STATIC_BLOCK;
  else
    {
      iter->d.block = block;

      /* A signal value meaning that we're iterating over a single
	 block.  */
      iter->which = FIRST_LOCAL_BLOCK;
      return;
    }

  compunit_symtab *cu = block->global_block ()->compunit ();

  /* If this is an included symtab, find the canonical includer and
     use it instead.  */
  while (cu->user != NULL)
    cu = cu->user;

  /* Putting this check here simplifies the logic of the iterator
     functions.  If there are no included symtabs, we only need to
     search a single block, so we might as well just do that
     directly.  */
  if (cu->includes == NULL)
    {
      iter->d.block = block;
      /* A signal value meaning that we're iterating over a single
	 block.  */
      iter->which = FIRST_LOCAL_BLOCK;
    }
  else
    {
      iter->d.compunit_symtab = cu;
      iter->which = which;
    }
}

/* A helper function that finds the current compunit over whose static
   or global block we should iterate.  */

static struct compunit_symtab *
find_iterator_compunit_symtab (struct block_iterator *iterator)
{
  if (iterator->idx == -1)
    return iterator->d.compunit_symtab;
  return iterator->d.compunit_symtab->includes[iterator->idx];
}

/* Perform a single step for a plain block iterator, iterating across
   symbol tables as needed.  Returns the next symbol, or NULL when
   iteration is complete.  */

static struct symbol *
block_iterator_step (struct block_iterator *iterator, int first)
{
  struct symbol *sym;

  gdb_assert (iterator->which != FIRST_LOCAL_BLOCK);

  while (1)
    {
      if (first)
	{
	  struct compunit_symtab *cust
	    = find_iterator_compunit_symtab (iterator);
	  const struct block *block;

	  /* Iteration is complete.  */
	  if (cust == NULL)
	    return  NULL;

	  block = cust->blockvector ()->block (iterator->which);
	  sym = mdict_iterator_first (block->multidict (),
				      &iterator->mdict_iter);
	}
      else
	sym = mdict_iterator_next (&iterator->mdict_iter);

      if (sym != NULL)
	return sym;

      /* We have finished iterating the appropriate block of one
	 symtab.  Now advance to the next symtab and begin iteration
	 there.  */
      ++iterator->idx;
      first = 1;
    }
}

/* Perform a single step for a "match" block iterator, iterating
   across symbol tables as needed.  Returns the next symbol, or NULL
   when iteration is complete.  */

static struct symbol *
block_iter_match_step (struct block_iterator *iterator,
		       int first)
{
  struct symbol *sym;

  gdb_assert (iterator->which != FIRST_LOCAL_BLOCK);

  while (1)
    {
      if (first)
	{
	  struct compunit_symtab *cust
	    = find_iterator_compunit_symtab (iterator);
	  const struct block *block;

	  /* Iteration is complete.  */
	  if (cust == NULL)
	    return  NULL;

	  block = cust->blockvector ()->block (iterator->which);
	  sym = mdict_iter_match_first (block->multidict (), *iterator->name,
					&iterator->mdict_iter);
	}
      else
	sym = mdict_iter_match_next (*iterator->name, &iterator->mdict_iter);

      if (sym != NULL)
	return sym;

      /* We have finished iterating the appropriate block of one
	 symtab.  Now advance to the next symtab and begin iteration
	 there.  */
      ++iterator->idx;
      first = 1;
    }
}

/* See block.h.  */

struct symbol *
block_iterator_first (const struct block *block,
		      struct block_iterator *iterator,
		      const lookup_name_info *name)
{
  initialize_block_iterator (block, iterator, name);

  if (name == nullptr)
    {
      if (iterator->which == FIRST_LOCAL_BLOCK)
	return mdict_iterator_first (block->multidict (),
				     &iterator->mdict_iter);

      return block_iterator_step (iterator, 1);
    }

  if (iterator->which == FIRST_LOCAL_BLOCK)
    return mdict_iter_match_first (block->multidict (), *name,
				   &iterator->mdict_iter);

  return block_iter_match_step (iterator, 1);
}

/* See block.h.  */

struct symbol *
block_iterator_next (struct block_iterator *iterator)
{
  if (iterator->name == nullptr)
    {
      if (iterator->which == FIRST_LOCAL_BLOCK)
	return mdict_iterator_next (&iterator->mdict_iter);

      return block_iterator_step (iterator, 0);
    }

  if (iterator->which == FIRST_LOCAL_BLOCK)
    return mdict_iter_match_next (*iterator->name, &iterator->mdict_iter);

  return block_iter_match_step (iterator, 0);
}

/* See block.h.  */

bool
best_symbol (struct symbol *a, const domain_search_flags domain)
{
  if (a->aclass () == LOC_UNRESOLVED)
    return false;

  if ((domain & SEARCH_VAR_DOMAIN) != 0)
    return a->domain () == VAR_DOMAIN;

  return a->matches (domain);
}

/* See block.h.  */

struct symbol *
better_symbol (struct symbol *a, struct symbol *b,
	       const domain_search_flags domain)
{
  if (a == NULL)
    return b;
  if (b == NULL)
    return a;

  if (a->matches (domain) && !b->matches (domain))
    return a;

  if (b->matches (domain) && !a->matches (domain))
    return b;

  if (a->aclass () != LOC_UNRESOLVED && b->aclass () == LOC_UNRESOLVED)
    return a;

  if (b->aclass () != LOC_UNRESOLVED && a->aclass () == LOC_UNRESOLVED)
    return b;

  return a;
}

/* See block.h.

   Note that if NAME is the demangled form of a C++ symbol, we will fail
   to find a match during the binary search of the non-encoded names, but
   for now we don't worry about the slight inefficiency of looking for
   a match we'll never find, since it will go pretty quick.  Once the
   binary search terminates, we drop through and do a straight linear
   search on the symbols.  Each symbol which is marked as being a ObjC/C++
   symbol (language_cplus or language_objc set) has both the encoded and
   non-encoded names tested for a match.  */

struct symbol *
block_lookup_symbol (const struct block *block, const lookup_name_info &name,
		     const domain_search_flags domain)
{
  if (!block->function ())
    {
      struct symbol *other = NULL;

      for (struct symbol *sym : block_iterator_range (block, &name))
	{
	  /* See comment related to PR gcc/debug/91507 in
	     block_lookup_symbol_primary.  */
	  if (best_symbol (sym, domain))
	    return sym;
	  /* This is a bit of a hack, but symbol_matches_domain might ignore
	     STRUCT vs VAR domain symbols.  So if a matching symbol is found,
	     make sure there is no "better" matching symbol, i.e., one with
	     exactly the same domain.  PR 16253.  */
	  if (sym->matches (domain))
	    other = better_symbol (other, sym, domain);
	}
      return other;
    }
  else
    {
      /* Note that parameter symbols do not always show up last in the
	 list; this loop makes sure to take anything else other than
	 parameter symbols first; it only uses parameter symbols as a
	 last resort.  Note that this only takes up extra computation
	 time on a match.
	 It's hard to define types in the parameter list (at least in
	 C/C++) so we don't do the same PR 16253 hack here that is done
	 for the !BLOCK_FUNCTION case.  */

      struct symbol *sym_found = NULL;

      for (struct symbol *sym : block_iterator_range (block, &name))
	{
	  if (sym->matches (domain))
	    {
	      sym_found = sym;
	      if (!sym->is_argument ())
		{
		  break;
		}
	    }
	}
      return (sym_found);	/* Will be NULL if not found.  */
    }
}

/* See block.h.  */

struct symbol *
block_lookup_symbol_primary (const struct block *block, const char *name,
			     const domain_search_flags domain)
{
  struct symbol *sym, *other;
  struct mdict_iterator mdict_iter;

  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);

  /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK.  */
  gdb_assert (block->superblock () == NULL
	      || block->superblock ()->superblock () == NULL);

  other = NULL;
  for (sym = mdict_iter_match_first (block->multidict (), lookup_name,
				     &mdict_iter);
       sym != NULL;
       sym = mdict_iter_match_next (lookup_name, &mdict_iter))
    {
      /* With the fix for PR gcc/debug/91507, we get for:
	 ...
	 extern char *zzz[];
	 char *zzz[ ] = {
	   "abc",
	   "cde"
	 };
	 ...
	 DWARF which will result in two entries in the symbol table, a decl
	 with type char *[] and a def with type char *[2].

	 If we return the decl here, we don't get the value of zzz:
	 ...
	 $ gdb a.spec.out -batch -ex "p zzz"
	 $1 = 0x601030 <zzz>
	 ...
	 because we're returning the symbol without location information, and
	 because the fallback that uses the address from the minimal symbols
	 doesn't work either because the type of the decl does not specify a
	 size.

	 To fix this, we prefer def over decl in best_symbol and
	 better_symbol.

	 In absence of the gcc fix, both def and decl have type char *[], so
	 the only option to make this work is improve the fallback to use the
	 size of the minimal symbol.  Filed as PR exp/24989.  */
      if (best_symbol (sym, domain))
	return sym;

      /* This is a bit of a hack, but 'matches' might ignore
	 STRUCT vs VAR domain symbols.  So if a matching symbol is found,
	 make sure there is no "better" matching symbol, i.e., one with
	 exactly the same domain.  PR 16253.  */
      if (sym->matches (domain))
	other = better_symbol (other, sym, domain);
    }

  return other;
}

/* See block.h.  */

struct symbol *
block_find_symbol (const struct block *block, const lookup_name_info &name,
		   const domain_search_flags domain, struct symbol **stub)
{
  /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK.  */
  gdb_assert (block->superblock () == NULL
	      || block->superblock ()->superblock () == NULL);

  for (struct symbol *sym : block_iterator_range (block, &name))
    {
      if (!sym->matches (domain))
	continue;

      if (!TYPE_IS_OPAQUE (sym->type ()))
	return sym;

      if (stub != nullptr)
	*stub = sym;
    }
  return nullptr;
}

/* See block.h.  */

struct blockranges *
make_blockranges (struct objfile *objfile,
		  const std::vector<blockrange> &rangevec)
{
  struct blockranges *blr;
  size_t n = rangevec.size();

  blr = (struct blockranges *)
    obstack_alloc (&objfile->objfile_obstack,
		   sizeof (struct blockranges)
		   + (n - 1) * sizeof (struct blockrange));

  blr->nranges = n;
  for (int i = 0; i < n; i++)
    blr->range[i] = rangevec[i];
  return blr;
}

/* Implement 'maint info blocks' command.  If passed an argument then
   print a list of all blocks at the given address.  With no arguments
   then list all blocks at the current address of the current inferior.  */

static void
maintenance_info_blocks (const char *arg, int from_tty)
{
  CORE_ADDR address;

  /* With no argument use the program counter of the current thread.  If
     there is an argument then use this as the address to examine.  */
  if (arg == nullptr)
    {
      if (inferior_ptid == null_ptid)
	error (_("no inferior thread"));

      struct regcache *regcache = get_thread_regcache (inferior_thread ());
      address = regcache_read_pc (regcache);
    }
  else
    address = parse_and_eval_address (arg);

  /* Find the inner most block for ADDRESS.  */
  const struct block *cur_block = block_for_pc (address);
  if (cur_block == nullptr)
    {
      gdb_printf (_("No blocks at %s\n"), core_addr_to_string_nz (address));
      return;
    }

  gdb_printf (_("Blocks at %s:\n"), core_addr_to_string_nz (address));

  const struct objfile *toplevel_objfile = cur_block->objfile ();
  if (toplevel_objfile != nullptr)
    gdb_printf (_("  from objfile: [(objfile *) %s] %s\n"),
		host_address_to_string (toplevel_objfile),
		objfile_name (toplevel_objfile));

  gdb_printf ("\n");

  /* List the blocks backwards; global block (widest scope) first, down to
     the smallest scoped block last.  To do this we need to build the list
     of blocks starting from the inner block, then print that list
     backwards.  */
  std::vector<const struct block *> blocks;
  while (cur_block != nullptr)
    {
      blocks.emplace_back (cur_block);
      cur_block = cur_block->superblock ();
    }

  for (auto it = blocks.rbegin (); it != blocks.rend (); ++it)
    {
      cur_block = *it;

      gdb_assert (cur_block->objfile () == toplevel_objfile);

      gdb_printf (_("[(block *) %s] %s..%s\n"),
		  host_address_to_string (cur_block),
		  core_addr_to_string_nz (cur_block->start ()),
		  core_addr_to_string_nz (cur_block->end ()));
      gdb_printf (_("  entry pc: %s\n"),
		  core_addr_to_string_nz (cur_block->entry_pc ()));

      if (cur_block->is_static_block ())
	gdb_printf (_("  is static block\n"));

      if (cur_block->is_global_block ())
	gdb_printf (_("  is global block\n"));

      if (cur_block->function () != nullptr)
	{
	  if (cur_block->inlined_p ())
	    gdb_printf (_("  inline function: %s\n"),
			cur_block->function ()->print_name ());
	  else
	    gdb_printf (_("  function: %s\n"),
			cur_block->function ()->print_name ());
	}

      if (cur_block->scope () != nullptr
	  && *cur_block->scope () != '\0')
	gdb_printf (_("  scope: %s\n"), cur_block->scope ());

      if (int symbol_count = mdict_size (cur_block->multidict ());
	  symbol_count > 0)
	gdb_printf (_("  symbol count: %d\n"), symbol_count);

      if (cur_block->is_contiguous ())
	gdb_printf (_("  is contiguous\n"));
      else
	{
	  gdb_printf (_("  address ranges:\n"));
	  for (const blockrange &rng : cur_block->ranges ())
	    gdb_printf (_("    %s..%s\n"),
			core_addr_to_string_nz (rng.start ()),
			core_addr_to_string_nz (rng.end ()));
	}
    }
}



void _initialize_block ();
void
_initialize_block ()
{
  add_cmd ("blocks", class_maintenance, maintenance_info_blocks,
	   _("\
Display block information for current thread.\n\
\n\
Usage:\n\
\n\
  maintenance info blocks [ADDRESS]\n\
\n\
With no ADDRESS show all blocks at the current address, starting with the\n\
global block and working down to the inner most block.\n\
\n\
When ADDRESS is given, list the blocks at ADDRESS."),
	   &maintenanceinfolist);
}
