/* Everything about load/unload catchpoints, for GDB.

   Copyright (C) 1986-2022 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 "defs.h"

#include "annotate.h"
#include "arch-utils.h"
#include "breakpoint.h"
#include "cli/cli-decode.h"
#include "mi/mi-common.h"
#include "progspace.h"
#include "solist.h"
#include "target.h"
#include "valprint.h"

/* An instance of this type is used to represent an solib catchpoint.
   A breakpoint is really of this type iff its ops pointer points to
   CATCH_SOLIB_BREAKPOINT_OPS.  */

struct solib_catchpoint : public catchpoint
{
  solib_catchpoint (struct gdbarch *gdbarch, bool temp,
		    const char *cond_string,
		    bool is_load_, const char *arg)
    : catchpoint (gdbarch, temp, cond_string),
      is_load (is_load_),
      regex (arg == nullptr ? nullptr : make_unique_xstrdup (arg)),
      compiled (arg == nullptr
		? nullptr
		: new compiled_regex (arg, REG_NOSUB, _("Invalid regexp")))
  {
  }

  int insert_location (struct bp_location *) override;
  int remove_location (struct bp_location *,
		       enum remove_bp_reason reason) override;
  int breakpoint_hit (const struct bp_location *bl,
		      const address_space *aspace,
		      CORE_ADDR bp_addr,
		      const target_waitstatus &ws) override;
  void check_status (struct bpstat *bs) override;
  enum print_stop_action print_it (const bpstat *bs) const override;
  bool print_one (bp_location **) const override;
  void print_mention () const override;
  void print_recreate (struct ui_file *fp) const override;

  /* True for "catch load", false for "catch unload".  */
  bool is_load;

  /* Regular expression to match, if any.  COMPILED is only valid when
     REGEX is non-NULL.  */
  gdb::unique_xmalloc_ptr<char> regex;
  std::unique_ptr<compiled_regex> compiled;
};

int
solib_catchpoint::insert_location (struct bp_location *ignore)
{
  return 0;
}

int
solib_catchpoint::remove_location (struct bp_location *ignore,
				   enum remove_bp_reason reason)
{
  return 0;
}

int
solib_catchpoint::breakpoint_hit (const struct bp_location *bl,
				  const address_space *aspace,
				  CORE_ADDR bp_addr,
				  const target_waitstatus &ws)
{
  if (ws.kind () == TARGET_WAITKIND_LOADED)
    return 1;

  for (breakpoint *other : all_breakpoints ())
    {
      if (other == bl->owner)
	continue;

      if (other->type != bp_shlib_event)
	continue;

      if (pspace != NULL && other->pspace != pspace)
	continue;

      for (bp_location *other_bl : other->locations ())
	{
	  if (other->breakpoint_hit (other_bl, aspace, bp_addr, ws))
	    return 1;
	}
    }

  return 0;
}

void
solib_catchpoint::check_status (struct bpstat *bs)
{
  if (is_load)
    {
      for (so_list *iter : current_program_space->added_solibs)
	{
	  if (!regex
	      || compiled->exec (iter->so_name, 0, NULL, 0) == 0)
	    return;
	}
    }
  else
    {
      for (const std::string &iter : current_program_space->deleted_solibs)
	{
	  if (!regex
	      || compiled->exec (iter.c_str (), 0, NULL, 0) == 0)
	    return;
	}
    }

  bs->stop = 0;
  bs->print_it = print_it_noop;
}

enum print_stop_action
solib_catchpoint::print_it (const bpstat *bs) const
{
  struct breakpoint *b = bs->breakpoint_at;
  struct ui_out *uiout = current_uiout;

  annotate_catchpoint (b->number);
  maybe_print_thread_hit_breakpoint (uiout);
  if (b->disposition == disp_del)
    uiout->text ("Temporary catchpoint ");
  else
    uiout->text ("Catchpoint ");
  uiout->field_signed ("bkptno", b->number);
  uiout->text ("\n");
  if (uiout->is_mi_like_p ())
    uiout->field_string ("disp", bpdisp_text (b->disposition));
  print_solib_event (true);
  return PRINT_SRC_AND_LOC;
}

bool
solib_catchpoint::print_one (bp_location **locs) const
{
  struct value_print_options opts;
  struct ui_out *uiout = current_uiout;

  get_user_print_options (&opts);
  /* Field 4, the address, is omitted (which makes the columns not
     line up too nicely with the headers, but the effect is relatively
     readable).  */
  if (opts.addressprint)
    {
      annotate_field (4);
      uiout->field_skip ("addr");
    }

  std::string msg;
  annotate_field (5);
  if (is_load)
    {
      if (regex)
	msg = string_printf (_("load of library matching %s"),
			     regex.get ());
      else
	msg = _("load of library");
    }
  else
    {
      if (regex)
	msg = string_printf (_("unload of library matching %s"),
			     regex.get ());
      else
	msg = _("unload of library");
    }
  uiout->field_string ("what", msg);

  if (uiout->is_mi_like_p ())
    uiout->field_string ("catch-type", is_load ? "load" : "unload");

  return true;
}

void
solib_catchpoint::print_mention () const
{
  gdb_printf (_("Catchpoint %d (%s)"), number,
	      is_load ? "load" : "unload");
}

void
solib_catchpoint::print_recreate (struct ui_file *fp) const
{
  gdb_printf (fp, "%s %s",
	      disposition == disp_del ? "tcatch" : "catch",
	      is_load ? "load" : "unload");
  if (regex)
    gdb_printf (fp, " %s", regex.get ());
  gdb_printf (fp, "\n");
}

/* See breakpoint.h.  */

void
add_solib_catchpoint (const char *arg, bool is_load, bool is_temp, bool enabled)
{
  struct gdbarch *gdbarch = get_current_arch ();

  if (!arg)
    arg = "";
  arg = skip_spaces (arg);
  if (*arg == '\0')
    arg = nullptr;

  std::unique_ptr<solib_catchpoint> c (new solib_catchpoint (gdbarch, is_temp,
							     nullptr,
							     is_load, arg));

  c->enable_state = enabled ? bp_enabled : bp_disabled;

  install_breakpoint (0, std::move (c), 1);
}

/* A helper function that does all the work for "catch load" and
   "catch unload".  */

static void
catch_load_or_unload (const char *arg, int from_tty, int is_load,
		      struct cmd_list_element *command)
{
  const int enabled = 1;
  bool temp = command->context () == CATCH_TEMPORARY;

  add_solib_catchpoint (arg, is_load, temp, enabled);
}

static void
catch_load_command_1 (const char *arg, int from_tty,
		      struct cmd_list_element *command)
{
  catch_load_or_unload (arg, from_tty, 1, command);
}

static void
catch_unload_command_1 (const char *arg, int from_tty,
			struct cmd_list_element *command)
{
  catch_load_or_unload (arg, from_tty, 0, command);
}

void _initialize_break_catch_load ();
void
_initialize_break_catch_load ()
{
  add_catch_command ("load", _("Catch loads of shared libraries.\n\
Usage: catch load [REGEX]\n\
If REGEX is given, only stop for libraries matching the regular expression."),
		     catch_load_command_1,
		     NULL,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);
  add_catch_command ("unload", _("Catch unloads of shared libraries.\n\
Usage: catch unload [REGEX]\n\
If REGEX is given, only stop for libraries matching the regular expression."),
		     catch_unload_command_1,
		     NULL,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);
}
