/* Target used to communicate with the AMD Debugger API.

   Copyright (C) 2019-2023 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 "amd-dbgapi-target.h"
#include "amdgpu-tdep.h"
#include "async-event.h"
#include "cli/cli-cmds.h"
#include "cli/cli-style.h"
#include "inf-loop.h"
#include "inferior.h"
#include "objfiles.h"
#include "observable.h"
#include "registry.h"
#include "solib.h"
#include "target.h"

/* When true, print debug messages relating to the amd-dbgapi target.  */

static bool debug_amd_dbgapi = false;

/* Make a copy of S styled in green.  */

static std::string
make_green (const char *s)
{
  cli_style_option style (nullptr, ui_file_style::GREEN);
  string_file sf (true);
  gdb_printf (&sf, "%ps", styled_string (style.style(), s));
  return sf.release ();
}

/* Debug module names.  "amd-dbgapi" is for the target debug messages (this
   file), whereas "amd-dbgapi-lib" is for logging messages output by the
   amd-dbgapi library.  */

static const char *amd_dbgapi_debug_module_unstyled = "amd-dbgapi";
static const char *amd_dbgapi_lib_debug_module_unstyled
  = "amd-dbgapi-lib";

/* Styled variants of the above.  */

static const std::string amd_dbgapi_debug_module_styled
  = make_green (amd_dbgapi_debug_module_unstyled);
static const std::string amd_dbgapi_lib_debug_module_styled
  = make_green (amd_dbgapi_lib_debug_module_unstyled);

/* Return the styled or unstyled variant of the amd-dbgapi module name,
   depending on whether gdb_stdlog can emit colors.  */

static const char *
amd_dbgapi_debug_module ()
{
  if (gdb_stdlog->can_emit_style_escape ())
    return amd_dbgapi_debug_module_styled.c_str ();
  else
    return amd_dbgapi_debug_module_unstyled;
}

/* Same as the above, but for the amd-dbgapi-lib module name.  */

static const char *
amd_dbgapi_lib_debug_module ()
{
  if (gdb_stdlog->can_emit_style_escape ())
    return amd_dbgapi_lib_debug_module_styled.c_str ();
  else
    return amd_dbgapi_lib_debug_module_unstyled;
}

/* Print an amd-dbgapi debug statement.  */

#define amd_dbgapi_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (debug_amd_dbgapi, \
			      amd_dbgapi_debug_module (), \
			      fmt, ##__VA_ARGS__)

/* Print amd-dbgapi start/end debug statements.  */

#define AMD_DBGAPI_SCOPED_DEBUG_START_END(fmt, ...) \
    scoped_debug_start_end (debug_infrun, amd_dbgapi_debug_module (), \
			    fmt, ##__VA_ARGS__)

/* inferior_created observer token.  */

static gdb::observers::token amd_dbgapi_target_inferior_created_observer_token;

const gdb::observers::token &
get_amd_dbgapi_target_inferior_created_observer_token ()
{
  return amd_dbgapi_target_inferior_created_observer_token;
}


/* Big enough to hold the size of the largest register in bytes.  */
#define AMDGPU_MAX_REGISTER_SIZE 256

/* amd-dbgapi-specific inferior data.  */

struct amd_dbgapi_inferior_info
{
  explicit amd_dbgapi_inferior_info (inferior *inf)
    : inf (inf)
  {}

  /* Backlink to inferior.  */
  inferior *inf;

  /* The amd_dbgapi_process_id for this inferior.  */
  amd_dbgapi_process_id_t process_id = AMD_DBGAPI_PROCESS_NONE;

  /* The amd_dbgapi_notifier_t for this inferior.  */
  amd_dbgapi_notifier_t notifier = -1;

  /* The status of the inferior's runtime support.  */
  amd_dbgapi_runtime_state_t runtime_state = AMD_DBGAPI_RUNTIME_STATE_UNLOADED;

  /* This value mirrors the current "forward progress needed" value for this
     process in amd-dbgapi.  It is used to avoid unnecessary calls to
     amd_dbgapi_process_set_progress, to reduce the noise in the logs.

     Initialized to true, since that's the default in amd-dbgapi too.  */
  bool forward_progress_required = true;

  std::unordered_map<decltype (amd_dbgapi_breakpoint_id_t::handle),
		     struct breakpoint *>
    breakpoint_map;

  /* List of pending events the amd-dbgapi target retrieved from the dbgapi.  */
  std::list<std::pair<ptid_t, target_waitstatus>> wave_events;
};

static amd_dbgapi_event_id_t process_event_queue
  (amd_dbgapi_process_id_t process_id,
   amd_dbgapi_event_kind_t until_event_kind = AMD_DBGAPI_EVENT_KIND_NONE);

static const target_info amd_dbgapi_target_info = {
  "amd-dbgapi",
  N_("AMD Debugger API"),
  N_("GPU debugging using the AMD Debugger API")
};

static amd_dbgapi_log_level_t get_debug_amd_dbgapi_lib_log_level ();

struct amd_dbgapi_target final : public target_ops
{
  const target_info &
  info () const override
  {
    return amd_dbgapi_target_info;
  }
  strata
  stratum () const override
  {
    return arch_stratum;
  }

  void close () override;
  void mourn_inferior () override;
  void detach (inferior *inf, int from_tty) override;

  void async (bool enable) override;

  bool has_pending_events () override;
  ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
  void resume (ptid_t, int, enum gdb_signal) override;
  void commit_resumed () override;
  void stop (ptid_t ptid) override;

  void fetch_registers (struct regcache *, int) override;
  void store_registers (struct regcache *, int) override;

  void update_thread_list () override;

  struct gdbarch *thread_architecture (ptid_t) override;

  void thread_events (int enable) override;

  std::string pid_to_str (ptid_t ptid) override;

  const char *thread_name (thread_info *tp) override;

  const char *extra_thread_info (thread_info *tp) override;

  bool thread_alive (ptid_t ptid) override;

  enum target_xfer_status xfer_partial (enum target_object object,
					const char *annex, gdb_byte *readbuf,
					const gdb_byte *writebuf,
					ULONGEST offset, ULONGEST len,
					ULONGEST *xfered_len) override;

  bool stopped_by_watchpoint () override;

  bool stopped_by_sw_breakpoint () override;
  bool stopped_by_hw_breakpoint () override;

private:
  /* True if we must report thread events.  */
  bool m_report_thread_events = false;

  /* Cache for the last value returned by thread_architecture.  */
  gdbarch *m_cached_arch = nullptr;
  ptid_t::tid_type m_cached_arch_tid = 0;
};

static struct amd_dbgapi_target the_amd_dbgapi_target;

/* Per-inferior data key.  */

static const registry<inferior>::key<amd_dbgapi_inferior_info>
  amd_dbgapi_inferior_data;

/* The async event handler registered with the event loop, indicating that we
   might have events to report to the core and that we'd like our wait method
   to be called.

   This is nullptr when async is disabled and non-nullptr when async is
   enabled.

   It is marked when a notifier fd tells us there's an event available.  The
   callback triggers handle_inferior_event in order to pull the event from
   amd-dbgapi and handle it.  */

static async_event_handler *amd_dbgapi_async_event_handler = nullptr;

/* Return the target id string for a given wave.  */

static std::string
wave_target_id_string (amd_dbgapi_wave_id_t wave_id)
{
  amd_dbgapi_dispatch_id_t dispatch_id;
  amd_dbgapi_queue_id_t queue_id;
  amd_dbgapi_agent_id_t agent_id;
  uint32_t group_ids[3], wave_in_group;
  std::string str = "AMDGPU Wave";

  amd_dbgapi_status_t status
    = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_AGENT,
				sizeof (agent_id), &agent_id);
  str += (status == AMD_DBGAPI_STATUS_SUCCESS
	  ? string_printf (" %ld", agent_id.handle)
	  : " ?");

  status = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_QUEUE,
				     sizeof (queue_id), &queue_id);
  str += (status == AMD_DBGAPI_STATUS_SUCCESS
	  ? string_printf (":%ld", queue_id.handle)
	  : ":?");

  status = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_DISPATCH,
				     sizeof (dispatch_id), &dispatch_id);
  str += (status == AMD_DBGAPI_STATUS_SUCCESS
	  ? string_printf (":%ld", dispatch_id.handle)
	  : ":?");

  str += string_printf (":%ld", wave_id.handle);

  status = amd_dbgapi_wave_get_info (wave_id,
				     AMD_DBGAPI_WAVE_INFO_WORKGROUP_COORD,
				     sizeof (group_ids), &group_ids);
  str += (status == AMD_DBGAPI_STATUS_SUCCESS
	  ? string_printf (" (%d,%d,%d)", group_ids[0], group_ids[1],
			   group_ids[2])
	  : " (?,?,?)");

  status = amd_dbgapi_wave_get_info
    (wave_id, AMD_DBGAPI_WAVE_INFO_WAVE_NUMBER_IN_WORKGROUP,
     sizeof (wave_in_group), &wave_in_group);
  str += (status == AMD_DBGAPI_STATUS_SUCCESS
	  ? string_printf ("/%d", wave_in_group)
	  : "/?");

  return str;
}

/* Clear our async event handler.  */

static void
async_event_handler_clear ()
{
  gdb_assert (amd_dbgapi_async_event_handler != nullptr);
  clear_async_event_handler (amd_dbgapi_async_event_handler);
}

/* Mark our async event handler.  */

static void
async_event_handler_mark ()
{
  gdb_assert (amd_dbgapi_async_event_handler != nullptr);
  mark_async_event_handler (amd_dbgapi_async_event_handler);
}

/* Fetch the amd_dbgapi_inferior_info data for the given inferior.  */

static struct amd_dbgapi_inferior_info *
get_amd_dbgapi_inferior_info (struct inferior *inferior)
{
  amd_dbgapi_inferior_info *info = amd_dbgapi_inferior_data.get (inferior);

  if (info == nullptr)
    info = amd_dbgapi_inferior_data.emplace (inferior, inferior);

  return info;
}

/* Set forward progress requirement to REQUIRE for all processes of PROC_TARGET
   matching PTID.  */

static void
require_forward_progress (ptid_t ptid, process_stratum_target *proc_target,
			  bool require)
{
  for (inferior *inf : all_inferiors (proc_target))
    {
      if (ptid != minus_one_ptid && inf->pid != ptid.pid ())
	continue;

      amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);

      if (info->process_id == AMD_DBGAPI_PROCESS_NONE)
	continue;

      /* Don't do unnecessary calls to amd-dbgapi to avoid polluting the logs.  */
      if (info->forward_progress_required == require)
	continue;

      amd_dbgapi_status_t status
	= amd_dbgapi_process_set_progress
	    (info->process_id, (require
				? AMD_DBGAPI_PROGRESS_NORMAL
				: AMD_DBGAPI_PROGRESS_NO_FORWARD));
      gdb_assert (status == AMD_DBGAPI_STATUS_SUCCESS);

      info->forward_progress_required = require;

      /* If ptid targets a single inferior and we have found it, no need to
	 continue.  */
      if (ptid != minus_one_ptid)
	break;
    }
}

/* See amd-dbgapi-target.h.  */

amd_dbgapi_process_id_t
get_amd_dbgapi_process_id (inferior *inf)
{
  return get_amd_dbgapi_inferior_info (inf)->process_id;
}

/* A breakpoint dbgapi wants us to insert, to handle shared library
   loading/unloading.  */

struct amd_dbgapi_target_breakpoint : public code_breakpoint
{
  amd_dbgapi_target_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
    : code_breakpoint (gdbarch, bp_breakpoint)
  {
    symtab_and_line sal;
    sal.pc = address;
    sal.section = find_pc_overlay (sal.pc);
    sal.pspace = current_program_space;
    add_location (sal);

    pspace = current_program_space;
    disposition = disp_donttouch;
  }

  void re_set () override;
  void check_status (struct bpstat *bs) override;
};

void
amd_dbgapi_target_breakpoint::re_set ()
{
  /* Nothing.  */
}

void
amd_dbgapi_target_breakpoint::check_status (struct bpstat *bs)
{
  inferior *inf = current_inferior ();
  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
  amd_dbgapi_status_t status;

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

  /* Find the address the breakpoint is set at.  */
  auto match_breakpoint
    = [bs] (const decltype (info->breakpoint_map)::value_type &value)
      { return value.second == bs->breakpoint_at; };
  auto it
    = std::find_if (info->breakpoint_map.begin (), info->breakpoint_map.end (),
		    match_breakpoint);

  if (it == info->breakpoint_map.end ())
    error (_("Could not find breakpoint_id for breakpoint at %s"),
	   paddress (inf->gdbarch, bs->bp_location_at->address));

  amd_dbgapi_breakpoint_id_t breakpoint_id { it->first };
  amd_dbgapi_breakpoint_action_t action;

  status = amd_dbgapi_report_breakpoint_hit
    (breakpoint_id,
     reinterpret_cast<amd_dbgapi_client_thread_id_t> (inferior_thread ()),
     &action);

  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("amd_dbgapi_report_breakpoint_hit failed for breakpoint %ld "
	     "at %s (%s)"),
	   breakpoint_id.handle, paddress (inf->gdbarch, bs->bp_location_at->address),
	   get_status_string (status));

  if (action == AMD_DBGAPI_BREAKPOINT_ACTION_RESUME)
    return;

  /* If the action is AMD_DBGAPI_BREAKPOINT_ACTION_HALT, we need to wait until
     a breakpoint resume event for this breakpoint_id is seen.  */
  amd_dbgapi_event_id_t resume_event_id
    = process_event_queue (info->process_id,
			   AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME);

  /* We should always get a breakpoint_resume event after processing all
     events generated by reporting the breakpoint hit.  */
  gdb_assert (resume_event_id != AMD_DBGAPI_EVENT_NONE);

  amd_dbgapi_breakpoint_id_t resume_breakpoint_id;
  status = amd_dbgapi_event_get_info (resume_event_id,
				      AMD_DBGAPI_EVENT_INFO_BREAKPOINT,
				      sizeof (resume_breakpoint_id),
				      &resume_breakpoint_id);

  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("amd_dbgapi_event_get_info failed (%s)"), get_status_string (status));

  /* The debugger API guarantees that [breakpoint_hit...resume_breakpoint]
     sequences cannot interleave, so this breakpoint resume event must be
     for our breakpoint_id.  */
  if (resume_breakpoint_id != breakpoint_id)
    error (_("breakpoint resume event is not for this breakpoint. "
	      "Expected breakpoint_%ld, got breakpoint_%ld"),
	   breakpoint_id.handle, resume_breakpoint_id.handle);

  amd_dbgapi_event_processed (resume_event_id);
}

bool
amd_dbgapi_target::thread_alive (ptid_t ptid)
{
  if (!ptid_is_gpu (ptid))
    return beneath ()->thread_alive (ptid);

  /* Check that the wave_id is valid.  */

  amd_dbgapi_wave_state_t state;
  amd_dbgapi_status_t status
    = amd_dbgapi_wave_get_info (get_amd_dbgapi_wave_id (ptid),
				AMD_DBGAPI_WAVE_INFO_STATE, sizeof (state),
				&state);
  return status == AMD_DBGAPI_STATUS_SUCCESS;
}

const char *
amd_dbgapi_target::thread_name (thread_info *tp)
{
  if (!ptid_is_gpu (tp->ptid))
    return beneath ()->thread_name (tp);

  return nullptr;
}

std::string
amd_dbgapi_target::pid_to_str (ptid_t ptid)
{
  if (!ptid_is_gpu (ptid))
    return beneath ()->pid_to_str (ptid);

  return wave_target_id_string (get_amd_dbgapi_wave_id (ptid));
}

const char *
amd_dbgapi_target::extra_thread_info (thread_info *tp)
{
  if (!ptid_is_gpu (tp->ptid))
    beneath ()->extra_thread_info (tp);

  return nullptr;
}

target_xfer_status
amd_dbgapi_target::xfer_partial (enum target_object object, const char *annex,
			       gdb_byte *readbuf, const gdb_byte *writebuf,
			       ULONGEST offset, ULONGEST requested_len,
			       ULONGEST *xfered_len)
{
  gdb::optional<scoped_restore_current_thread> maybe_restore_thread;

  if (!ptid_is_gpu (inferior_ptid))
    return beneath ()->xfer_partial (object, annex, readbuf, writebuf, offset,
				     requested_len, xfered_len);

  gdb_assert (requested_len > 0);
  gdb_assert (xfered_len != nullptr);

  if (object != TARGET_OBJECT_MEMORY)
    return TARGET_XFER_E_IO;

  amd_dbgapi_process_id_t process_id
    = get_amd_dbgapi_process_id (current_inferior ());
  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (inferior_ptid);

  size_t len = requested_len;
  amd_dbgapi_status_t status;

  if (readbuf != nullptr)
    status = amd_dbgapi_read_memory (process_id, wave_id, 0,
				     AMD_DBGAPI_ADDRESS_SPACE_GLOBAL,
				     offset, &len, readbuf);
  else
    status = amd_dbgapi_write_memory (process_id, wave_id, 0,
				      AMD_DBGAPI_ADDRESS_SPACE_GLOBAL,
				      offset, &len, writebuf);

  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    return TARGET_XFER_E_IO;

  *xfered_len = len;
  return TARGET_XFER_OK;
}

bool
amd_dbgapi_target::stopped_by_watchpoint ()
{
  if (!ptid_is_gpu (inferior_ptid))
    return beneath ()->stopped_by_watchpoint ();

  return false;
}

void
amd_dbgapi_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo)
{
  amd_dbgapi_debug_printf ("scope_ptid = %s", scope_ptid.to_string ().c_str ());

  /* The amd_dbgapi_exceptions_t matching SIGNO will only be used if the
     thread which is the target of the signal SIGNO is a GPU thread.  If so,
     make sure that there is a corresponding amd_dbgapi_exceptions_t for SIGNO
     before we try to resume any thread.  */
  amd_dbgapi_exceptions_t exception = AMD_DBGAPI_EXCEPTION_NONE;
  if (ptid_is_gpu (inferior_ptid))
    {
      switch (signo)
	{
	case GDB_SIGNAL_BUS:
	  exception = AMD_DBGAPI_EXCEPTION_WAVE_APERTURE_VIOLATION;
	  break;
	case GDB_SIGNAL_SEGV:
	  exception = AMD_DBGAPI_EXCEPTION_WAVE_MEMORY_VIOLATION;
	  break;
	case GDB_SIGNAL_ILL:
	  exception = AMD_DBGAPI_EXCEPTION_WAVE_ILLEGAL_INSTRUCTION;
	  break;
	case GDB_SIGNAL_FPE:
	  exception = AMD_DBGAPI_EXCEPTION_WAVE_MATH_ERROR;
	  break;
	case GDB_SIGNAL_ABRT:
	  exception = AMD_DBGAPI_EXCEPTION_WAVE_ABORT;
	  break;
	case GDB_SIGNAL_TRAP:
	  exception = AMD_DBGAPI_EXCEPTION_WAVE_TRAP;
	  break;
	case GDB_SIGNAL_0:
	  exception = AMD_DBGAPI_EXCEPTION_NONE;
	  break;
	default:
	  error (_("Resuming with signal %s is not supported by this agent."),
		 gdb_signal_to_name (signo));
	}
    }

  if (!ptid_is_gpu (inferior_ptid) || scope_ptid != inferior_ptid)
    {
      beneath ()->resume (scope_ptid, step, signo);

      /* If the request is for a single thread, we are done.  */
      if (scope_ptid == inferior_ptid)
	return;
    }

  process_stratum_target *proc_target = current_inferior ()->process_target ();

  /* Disable forward progress requirement.  */
  require_forward_progress (scope_ptid, proc_target, false);

  for (thread_info *thread : all_non_exited_threads (proc_target, scope_ptid))
    {
      if (!ptid_is_gpu (thread->ptid))
	continue;

      amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (thread->ptid);
      amd_dbgapi_status_t status;
      if (thread->ptid == inferior_ptid)
	status = amd_dbgapi_wave_resume (wave_id,
					 (step
					  ? AMD_DBGAPI_RESUME_MODE_SINGLE_STEP
					  : AMD_DBGAPI_RESUME_MODE_NORMAL),
					 exception);
      else
	status = amd_dbgapi_wave_resume (wave_id, AMD_DBGAPI_RESUME_MODE_NORMAL,
					 AMD_DBGAPI_EXCEPTION_NONE);

      if (status != AMD_DBGAPI_STATUS_SUCCESS
	  /* Ignore the error that wave is no longer valid as that could
	     indicate that the process has exited.  GDB treats resuming a
	     thread that no longer exists as being successful.  */
	  && status != AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID)
	error (_("wave_resume for wave_%ld failed (%s)"), wave_id.handle,
	       get_status_string (status));
    }
}

void
amd_dbgapi_target::commit_resumed ()
{
  amd_dbgapi_debug_printf ("called");

  beneath ()->commit_resumed ();

  process_stratum_target *proc_target = current_inferior ()->process_target ();
  require_forward_progress (minus_one_ptid, proc_target, true);
}

void
amd_dbgapi_target::stop (ptid_t ptid)
{
  amd_dbgapi_debug_printf ("ptid = %s", ptid.to_string ().c_str ());

  bool many_threads = ptid == minus_one_ptid || ptid.is_pid ();

  if (!ptid_is_gpu (ptid) || many_threads)
    {
      beneath ()->stop (ptid);

      /* The request is for a single thread, we are done.  */
      if (!many_threads)
	return;
    }

  auto stop_one_thread = [this] (thread_info *thread)
    {
      gdb_assert (thread != nullptr);

      amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (thread->ptid);
      amd_dbgapi_wave_state_t state;
      amd_dbgapi_status_t status
	= amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_STATE,
				    sizeof (state), &state);
      if (status == AMD_DBGAPI_STATUS_SUCCESS)
	{
	  /* If the wave is already known to be stopped then do nothing.  */
	  if (state == AMD_DBGAPI_WAVE_STATE_STOP)
	    return;

	  status = amd_dbgapi_wave_stop (wave_id);
	  if (status == AMD_DBGAPI_STATUS_SUCCESS)
	    return;

	  if (status != AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID)
	    error (_("wave_stop for wave_%ld failed (%s)"), wave_id.handle,
		   get_status_string (status));
	}
      else if (status != AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID)
	error (_("wave_get_info for wave_%ld failed (%s)"), wave_id.handle,
	       get_status_string (status));

      /* The status is AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID.  The wave
	 could have terminated since the last time the wave list was
	 refreshed.  */

      if (m_report_thread_events)
	{
	  get_amd_dbgapi_inferior_info (thread->inf)->wave_events.emplace_back
	    (thread->ptid, target_waitstatus ().set_thread_exited (0));

	  if (target_is_async_p ())
	    async_event_handler_mark ();
	}

      delete_thread_silent (thread);
    };

  process_stratum_target *proc_target = current_inferior ()->process_target ();

  /* Disable forward progress requirement.  */
  require_forward_progress (ptid, proc_target, false);

  if (!many_threads)
    {
      /* No need to iterate all non-exited threads if the request is to stop a
	 specific thread.  */
      stop_one_thread (proc_target->find_thread (ptid));
      return;
    }

  for (auto *inf : all_inferiors (proc_target))
    /* Use the threads_safe iterator since stop_one_thread may delete the
       thread if it has exited.  */
    for (auto *thread : inf->threads_safe ())
      if (thread->state != THREAD_EXITED && thread->ptid.matches (ptid)
	  && ptid_is_gpu (thread->ptid))
	stop_one_thread (thread);
}

/* Callback for our async event handler.  */

static void
handle_target_event (gdb_client_data client_data)
{
  inferior_event_handler (INF_REG_EVENT);
}

struct scoped_amd_dbgapi_event_processed
{
  scoped_amd_dbgapi_event_processed (amd_dbgapi_event_id_t event_id)
    : m_event_id (event_id)
  {
    gdb_assert (event_id != AMD_DBGAPI_EVENT_NONE);
  }

  ~scoped_amd_dbgapi_event_processed ()
  {
    amd_dbgapi_status_t status = amd_dbgapi_event_processed (m_event_id);
    if (status != AMD_DBGAPI_STATUS_SUCCESS)
      warning (_("Failed to acknowledge amd-dbgapi event %" PRIu64),
	       m_event_id.handle);
  }

  DISABLE_COPY_AND_ASSIGN (scoped_amd_dbgapi_event_processed);

private:
  amd_dbgapi_event_id_t m_event_id;
};

/* Called when a dbgapi notifier fd is readable.  CLIENT_DATA is the
   amd_dbgapi_inferior_info object corresponding to the notifier.  */

static void
dbgapi_notifier_handler (int err, gdb_client_data client_data)
{
  amd_dbgapi_inferior_info *info = (amd_dbgapi_inferior_info *) client_data;
  int ret;

  /* Drain the notifier pipe.  */
  do
    {
      char buf;
      ret = read (info->notifier, &buf, 1);
    }
  while (ret >= 0 || (ret == -1 && errno == EINTR));

  if (info->inf->target_is_pushed (&the_amd_dbgapi_target))
    {
      /* The amd-dbgapi target is pushed: signal our async handler, the event
	 will be consumed through our wait method.  */

      async_event_handler_mark ();
    }
  else
    {
      /* The amd-dbgapi target is not pushed: if there's an event, the only
	 expected one is one of the RUNTIME kind.  If the event tells us the
	 inferior as activated the ROCm runtime, push the amd-dbgapi
	 target.  */

      amd_dbgapi_event_id_t event_id;
      amd_dbgapi_event_kind_t event_kind;
      amd_dbgapi_status_t status
	= amd_dbgapi_process_next_pending_event (info->process_id, &event_id,
						 &event_kind);
      if (status != AMD_DBGAPI_STATUS_SUCCESS)
	error (_("next_pending_event failed (%s)"), get_status_string (status));

      if (event_id == AMD_DBGAPI_EVENT_NONE)
	return;

      gdb_assert (event_kind == AMD_DBGAPI_EVENT_KIND_RUNTIME);

      scoped_amd_dbgapi_event_processed mark_event_processed (event_id);

      amd_dbgapi_runtime_state_t runtime_state;
      status = amd_dbgapi_event_get_info (event_id,
					  AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE,
					  sizeof (runtime_state),
					  &runtime_state);
      if (status != AMD_DBGAPI_STATUS_SUCCESS)
	error (_("event_get_info for event_%ld failed (%s)"),
	       event_id.handle, get_status_string (status));

      switch (runtime_state)
	{
	case AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS:
	  gdb_assert (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED);
	  info->runtime_state = runtime_state;
	  amd_dbgapi_debug_printf ("pushing amd-dbgapi target");
	  info->inf->push_target (&the_amd_dbgapi_target);

	  /* The underlying target will already be async if we are running, but not if
	     we are attaching.  */
	  if (info->inf->process_target ()->is_async_p ())
	    {
	      scoped_restore_current_thread restore_thread;
	      switch_to_inferior_no_thread (info->inf);

	      /* Make sure our async event handler is created.  */
	      target_async (true);
	    }
	  break;

	case AMD_DBGAPI_RUNTIME_STATE_UNLOADED:
	  gdb_assert (info->runtime_state
		      == AMD_DBGAPI_RUNTIME_STATE_LOADED_ERROR_RESTRICTION);
	  info->runtime_state = runtime_state;
	  break;

	case AMD_DBGAPI_RUNTIME_STATE_LOADED_ERROR_RESTRICTION:
	  gdb_assert (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED);
	  info->runtime_state = runtime_state;
	  warning (_("amd-dbgapi: unable to enable GPU debugging "
		     "due to a restriction error"));
	  break;
	}
    }
}

void
amd_dbgapi_target::async (bool enable)
{
  beneath ()->async (enable);

  if (enable)
    {
      if (amd_dbgapi_async_event_handler != nullptr)
	{
	  /* Already enabled.  */
	  return;
	}

      /* The library gives us one notifier file descriptor per inferior (even
	 the ones that have not yet loaded their runtime).  Register them
	 all with the event loop.  */
      process_stratum_target *proc_target
	= current_inferior ()->process_target ();

      for (inferior *inf : all_non_exited_inferiors (proc_target))
	{
	  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);

	  if (info->notifier != -1)
	    add_file_handler (info->notifier, dbgapi_notifier_handler, info,
			      string_printf ("amd-dbgapi notifier for pid %d",
					     inf->pid));
	}

      amd_dbgapi_async_event_handler
	= create_async_event_handler (handle_target_event, nullptr,
				      "amd-dbgapi");

      /* There may be pending events to handle.  Tell the event loop to poll
	 them.  */
      async_event_handler_mark ();
    }
  else
    {
      if (amd_dbgapi_async_event_handler == nullptr)
	return;

      for (inferior *inf : all_inferiors ())
	{
	  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);

	  if (info->notifier != -1)
	    delete_file_handler (info->notifier);
	}

      delete_async_event_handler (&amd_dbgapi_async_event_handler);
    }
}

/* Make a ptid for a GPU wave.  See comment on ptid_is_gpu for more details.  */

static ptid_t
make_gpu_ptid (ptid_t::pid_type pid, amd_dbgapi_wave_id_t wave_id)
{
 return ptid_t (pid, 1, wave_id.handle);
}

/* Process an event that was just pulled out of the amd-dbgapi library.  */

static void
process_one_event (amd_dbgapi_event_id_t event_id,
		   amd_dbgapi_event_kind_t event_kind)
{
  /* Automatically mark this event processed when going out of scope.  */
  scoped_amd_dbgapi_event_processed mark_event_processed (event_id);

  amd_dbgapi_process_id_t process_id;
  amd_dbgapi_status_t status
    = amd_dbgapi_event_get_info (event_id, AMD_DBGAPI_EVENT_INFO_PROCESS,
				 sizeof (process_id), &process_id);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("event_get_info for event_%ld failed (%s)"), event_id.handle,
	   get_status_string (status));

  amd_dbgapi_os_process_id_t pid;
  status = amd_dbgapi_process_get_info (process_id,
					AMD_DBGAPI_PROCESS_INFO_OS_ID,
					sizeof (pid), &pid);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("process_get_info for process_%ld failed (%s)"),
	   process_id.handle, get_status_string (status));

  auto *proc_target = current_inferior ()->process_target ();
  inferior *inf = find_inferior_pid (proc_target, pid);
  gdb_assert (inf != nullptr);
  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);

  switch (event_kind)
    {
    case AMD_DBGAPI_EVENT_KIND_WAVE_COMMAND_TERMINATED:
    case AMD_DBGAPI_EVENT_KIND_WAVE_STOP:
      {
	amd_dbgapi_wave_id_t wave_id;
	status
	  = amd_dbgapi_event_get_info (event_id, AMD_DBGAPI_EVENT_INFO_WAVE,
				       sizeof (wave_id), &wave_id);
	if (status != AMD_DBGAPI_STATUS_SUCCESS)
	  error (_("event_get_info for event_%ld failed (%s)"),
		 event_id.handle, get_status_string (status));

	ptid_t event_ptid = make_gpu_ptid (pid, wave_id);
	target_waitstatus ws;

	amd_dbgapi_wave_stop_reasons_t stop_reason;
	status = amd_dbgapi_wave_get_info (wave_id,
					   AMD_DBGAPI_WAVE_INFO_STOP_REASON,
					   sizeof (stop_reason), &stop_reason);
	if (status == AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID
	    && event_kind == AMD_DBGAPI_EVENT_KIND_WAVE_COMMAND_TERMINATED)
	  ws.set_thread_exited (0);
	else if (status == AMD_DBGAPI_STATUS_SUCCESS)
	  {
	    if (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_APERTURE_VIOLATION)
	      ws.set_stopped (GDB_SIGNAL_BUS);
	    else if (stop_reason
		     & AMD_DBGAPI_WAVE_STOP_REASON_MEMORY_VIOLATION)
	      ws.set_stopped (GDB_SIGNAL_SEGV);
	    else if (stop_reason
		     & AMD_DBGAPI_WAVE_STOP_REASON_ILLEGAL_INSTRUCTION)
	      ws.set_stopped (GDB_SIGNAL_ILL);
	    else if (stop_reason
		     & (AMD_DBGAPI_WAVE_STOP_REASON_FP_INPUT_DENORMAL
			| AMD_DBGAPI_WAVE_STOP_REASON_FP_DIVIDE_BY_0
			| AMD_DBGAPI_WAVE_STOP_REASON_FP_OVERFLOW
			| AMD_DBGAPI_WAVE_STOP_REASON_FP_UNDERFLOW
			| AMD_DBGAPI_WAVE_STOP_REASON_FP_INEXACT
			| AMD_DBGAPI_WAVE_STOP_REASON_FP_INVALID_OPERATION
			| AMD_DBGAPI_WAVE_STOP_REASON_INT_DIVIDE_BY_0))
	      ws.set_stopped (GDB_SIGNAL_FPE);
	    else if (stop_reason
		     & (AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT
			| AMD_DBGAPI_WAVE_STOP_REASON_WATCHPOINT
			| AMD_DBGAPI_WAVE_STOP_REASON_SINGLE_STEP
			| AMD_DBGAPI_WAVE_STOP_REASON_DEBUG_TRAP
			| AMD_DBGAPI_WAVE_STOP_REASON_TRAP))
	      ws.set_stopped (GDB_SIGNAL_TRAP);
	    else if (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_ASSERT_TRAP)
	      ws.set_stopped (GDB_SIGNAL_ABRT);
	    else
	      ws.set_stopped (GDB_SIGNAL_0);

	    thread_info *thread = proc_target->find_thread (event_ptid);
	    if (thread == nullptr)
	      {
		/* Silently create new GPU threads to avoid spamming the
		   terminal with thousands of "[New Thread ...]" messages.  */
		thread = add_thread_silent (proc_target, event_ptid);
		set_running (proc_target, event_ptid, true);
		set_executing (proc_target, event_ptid, true);
	      }

	    /* If the wave is stopped because of a software breakpoint, the
	       program counter needs to be adjusted so that it points to the
	       breakpoint instruction.  */
	    if ((stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT) != 0)
	      {
		regcache *regcache = get_thread_regcache (thread);
		gdbarch *gdbarch = regcache->arch ();

		CORE_ADDR pc = regcache_read_pc (regcache);
		CORE_ADDR adjusted_pc
		  = pc - gdbarch_decr_pc_after_break (gdbarch);

		if (adjusted_pc != pc)
		  regcache_write_pc (regcache, adjusted_pc);
	      }
	  }
	else
	  error (_("wave_get_info for wave_%ld failed (%s)"),
		 wave_id.handle, get_status_string (status));

	info->wave_events.emplace_back (event_ptid, ws);
	break;
      }

    case AMD_DBGAPI_EVENT_KIND_CODE_OBJECT_LIST_UPDATED:
      /* We get here when the following sequence of events happens:

	   - the inferior hits the amd-dbgapi "r_brk" internal breakpoint
	   - amd_dbgapi_target_breakpoint::check_status calls
	     amd_dbgapi_report_breakpoint_hit, which queues an event of this
	     kind in dbgapi
	   - amd_dbgapi_target_breakpoint::check_status calls
	     process_event_queue, which pulls the event out of dbgapi, and
	     gets us here

	 When amd_dbgapi_target_breakpoint::check_status is called, the current
	 inferior is the inferior that hit the breakpoint, which should still be
	 the case now.  */
      gdb_assert (inf == current_inferior ());
      handle_solib_event ();
      break;

    case AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME:
      /* Breakpoint resume events should be handled by the breakpoint
	 action, and this code should not reach this.  */
      gdb_assert_not_reached ("unhandled event kind");
      break;

    case AMD_DBGAPI_EVENT_KIND_RUNTIME:
      {
	amd_dbgapi_runtime_state_t runtime_state;

	status = amd_dbgapi_event_get_info (event_id,
					    AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE,
					    sizeof (runtime_state),
					    &runtime_state);
	if (status != AMD_DBGAPI_STATUS_SUCCESS)
	  error (_("event_get_info for event_%ld failed (%s)"),
		 event_id.handle, get_status_string (status));

	gdb_assert (runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED);
	gdb_assert
	  (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS);

	info->runtime_state = runtime_state;

	gdb_assert (inf->target_is_pushed (&the_amd_dbgapi_target));
	inf->unpush_target (&the_amd_dbgapi_target);
      }
      break;

    default:
      error (_("event kind (%d) not supported"), event_kind);
    }
}

/* Return a textual version of KIND.  */

static const char *
event_kind_str (amd_dbgapi_event_kind_t kind)
{
  switch (kind)
    {
    case AMD_DBGAPI_EVENT_KIND_NONE:
      return "NONE";

    case AMD_DBGAPI_EVENT_KIND_WAVE_STOP:
      return "WAVE_STOP";

    case AMD_DBGAPI_EVENT_KIND_WAVE_COMMAND_TERMINATED:
      return "WAVE_COMMAND_TERMINATED";

    case AMD_DBGAPI_EVENT_KIND_CODE_OBJECT_LIST_UPDATED:
      return "CODE_OBJECT_LIST_UPDATED";

    case AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME:
      return "BREAKPOINT_RESUME";

    case AMD_DBGAPI_EVENT_KIND_RUNTIME:
      return "RUNTIME";

    case AMD_DBGAPI_EVENT_KIND_QUEUE_ERROR:
      return "QUEUE_ERROR";
    }

  gdb_assert_not_reached ("unhandled amd_dbgapi_event_kind_t value");
}

/* Drain the dbgapi event queue of a given process_id, or of all processes if
   process_id is AMD_DBGAPI_PROCESS_NONE.  Stop processing the events if an
   event of a given kind is requested and `process_id` is not
   AMD_DBGAPI_PROCESS_NONE.  Wave stop events that are not returned are queued
   into their inferior's amd_dbgapi_inferior_info pending wave events. */

static amd_dbgapi_event_id_t
process_event_queue (amd_dbgapi_process_id_t process_id,
		     amd_dbgapi_event_kind_t until_event_kind)
{
  /* An event of a given type can only be requested from a single
     process_id.  */
  gdb_assert (until_event_kind == AMD_DBGAPI_EVENT_KIND_NONE
	      || process_id != AMD_DBGAPI_PROCESS_NONE);

  while (true)
    {
      amd_dbgapi_event_id_t event_id;
      amd_dbgapi_event_kind_t event_kind;

      amd_dbgapi_status_t status
	= amd_dbgapi_process_next_pending_event (process_id, &event_id,
						 &event_kind);

      if (status != AMD_DBGAPI_STATUS_SUCCESS)
	error (_("next_pending_event failed (%s)"), get_status_string (status));

      if (event_kind != AMD_DBGAPI_EVENT_KIND_NONE)
	amd_dbgapi_debug_printf ("Pulled event from dbgapi: "
				 "event_id.handle = %" PRIu64 ", "
				 "event_kind = %s",
				 event_id.handle,
				 event_kind_str (event_kind));

      if (event_id == AMD_DBGAPI_EVENT_NONE || event_kind == until_event_kind)
	return event_id;

      process_one_event (event_id, event_kind);
    }
}

bool
amd_dbgapi_target::has_pending_events ()
{
  if (amd_dbgapi_async_event_handler != nullptr
      && async_event_handler_marked (amd_dbgapi_async_event_handler))
    return true;

  return beneath ()->has_pending_events ();
}

/* Pop one pending event from the per-inferior structures.

   If PID is not -1, restrict the search to the inferior with that pid.  */

static std::pair<ptid_t, target_waitstatus>
consume_one_event (int pid)
{
  auto *target = current_inferior ()->process_target ();
  struct amd_dbgapi_inferior_info *info = nullptr;

  if (pid == -1)
    {
      for (inferior *inf : all_inferiors (target))
	{
	  info = get_amd_dbgapi_inferior_info (inf);
	  if (!info->wave_events.empty ())
	    break;
	}

      gdb_assert (info != nullptr);
    }
  else
    {
      inferior *inf = find_inferior_pid (target, pid);

      gdb_assert (inf != nullptr);
      info = get_amd_dbgapi_inferior_info (inf);
    }

  if (info->wave_events.empty ())
    return { minus_one_ptid, {} };

  auto event = info->wave_events.front ();
  info->wave_events.pop_front ();

  return event;
}

ptid_t
amd_dbgapi_target::wait (ptid_t ptid, struct target_waitstatus *ws,
		       target_wait_flags target_options)
{
  gdb_assert (!current_inferior ()->process_target ()->commit_resumed_state);
  gdb_assert (ptid == minus_one_ptid || ptid.is_pid ());

  amd_dbgapi_debug_printf ("ptid = %s", ptid.to_string ().c_str ());

  ptid_t event_ptid = beneath ()->wait (ptid, ws, target_options);
  if (event_ptid != minus_one_ptid)
    {
      if (ws->kind () == TARGET_WAITKIND_EXITED
	  || ws->kind () == TARGET_WAITKIND_SIGNALLED)
       {
	 /* This inferior has exited so drain its dbgapi event queue.  */
	 while (consume_one_event (event_ptid.pid ()).first
		!= minus_one_ptid)
	   ;
       }
      return event_ptid;
    }

  gdb_assert (ws->kind () == TARGET_WAITKIND_NO_RESUMED
	      || ws->kind () == TARGET_WAITKIND_IGNORE);

  /* Flush the async handler first.  */
  if (target_is_async_p ())
    async_event_handler_clear ();

  /* There may be more events to process (either already in `wave_events` or
     that we need to fetch from dbgapi.  Mark the async event handler so that
     amd_dbgapi_target::wait gets called again and again, until it eventually
     returns minus_one_ptid.  */
  auto more_events = make_scope_exit ([] ()
    {
      if (target_is_async_p ())
	async_event_handler_mark ();
    });

  auto *proc_target = current_inferior ()->process_target ();

  /* Disable forward progress for the specified pid in ptid if it isn't
     minus_on_ptid, or all attached processes if ptid is minus_one_ptid.  */
  require_forward_progress (ptid, proc_target, false);

  target_waitstatus gpu_waitstatus;
  std::tie (event_ptid, gpu_waitstatus) = consume_one_event (ptid.pid ());
  if (event_ptid == minus_one_ptid)
    {
      /* Drain the events for the current inferior from the amd_dbgapi and
	 preserve the ordering.  */
      auto info = get_amd_dbgapi_inferior_info (current_inferior ());
      process_event_queue (info->process_id, AMD_DBGAPI_EVENT_KIND_NONE);

      std::tie (event_ptid, gpu_waitstatus) = consume_one_event (ptid.pid ());
      if (event_ptid == minus_one_ptid)
	{
	  /* If we requested a specific ptid, and nothing came out, assume
	     another ptid may have more events, otherwise, keep the
	     async_event_handler flushed.  */
	  if (ptid == minus_one_ptid)
	    more_events.release ();

	  if (ws->kind () == TARGET_WAITKIND_NO_RESUMED)
	    {
	      /* We can't easily check that all GPU waves are stopped, and no
		 new waves can be created (the GPU has fixed function hardware
		 to create new threads), so even if the target beneath returns
		 waitkind_no_resumed, we have to report waitkind_ignore if GPU
		 debugging is enabled for at least one resumed inferior handled
		 by the amd-dbgapi target.  */

	      for (inferior *inf : all_inferiors ())
		if (inf->target_at (arch_stratum) == &the_amd_dbgapi_target
		    && get_amd_dbgapi_inferior_info (inf)->runtime_state
			 == AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS)
		  {
		    ws->set_ignore ();
		    break;
		  }
	    }

	  /* There are no events to report, return the target beneath's
	     waitstatus (either IGNORE or NO_RESUMED).  */
	  return minus_one_ptid;
	}
    }

  *ws = gpu_waitstatus;
  return event_ptid;
}

bool
amd_dbgapi_target::stopped_by_sw_breakpoint ()
{
  if (!ptid_is_gpu (inferior_ptid))
    return beneath ()->stopped_by_sw_breakpoint ();

  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (inferior_ptid);

  amd_dbgapi_wave_stop_reasons_t stop_reason;
  amd_dbgapi_status_t status
    = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_STOP_REASON,
				sizeof (stop_reason), &stop_reason);

  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    return false;

  return (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT) != 0;
}

bool
amd_dbgapi_target::stopped_by_hw_breakpoint ()
{
  if (!ptid_is_gpu (inferior_ptid))
    return beneath ()->stopped_by_hw_breakpoint ();

  return false;
}

/* Make the amd-dbgapi library attach to the process behind INF.

   Note that this is unrelated to the "attach" GDB concept / command.

   By attaching to the process, we get a notifier fd that tells us when it
   activates the ROCm runtime and when there are subsequent debug events.  */

static void
attach_amd_dbgapi (inferior *inf)
{
  AMD_DBGAPI_SCOPED_DEBUG_START_END ("inf num = %d", inf->num);

  if (!target_can_async_p ())
    {
      warning (_("The amd-dbgapi target requires the target beneath to be "
		 "asynchronous, GPU debugging is disabled"));
      return;
    }

  /* dbgapi can't attach to a vfork child (a process born from a vfork that
     hasn't exec'ed yet) while we are still attached to the parent.  It would
     not be useful for us to attach to vfork children anyway, because vfork
     children are very restricted in what they can do (see vfork(2)) and aren't
     going to launch some GPU programs that we need to debug.  To avoid this
     problem, we don't push the amd-dbgapi target / attach dbgapi in vfork
     children.  If a vfork child execs, we'll try enabling the amd-dbgapi target
     through the inferior_execd observer.  */
  if (inf->vfork_parent != nullptr)
    return;

  auto *info = get_amd_dbgapi_inferior_info (inf);

  /* Are we already attached?  */
  if (info->process_id != AMD_DBGAPI_PROCESS_NONE)
    {
      amd_dbgapi_debug_printf
	("already attached: process_id = %" PRIu64, info->process_id.handle);
      return;
    }

  amd_dbgapi_status_t status
    = amd_dbgapi_process_attach
	(reinterpret_cast<amd_dbgapi_client_process_id_t> (inf),
	 &info->process_id);
  if (status == AMD_DBGAPI_STATUS_ERROR_RESTRICTION)
    {
      warning (_("amd-dbgapi: unable to enable GPU debugging due to a "
		 "restriction error"));
      return;
    }
  else if (status != AMD_DBGAPI_STATUS_SUCCESS)
    {
      warning (_("amd-dbgapi: could not attach to process %d (%s), GPU "
		 "debugging will not be available."), inf->pid,
	       get_status_string (status));
      return;
    }

  if (amd_dbgapi_process_get_info (info->process_id,
				   AMD_DBGAPI_PROCESS_INFO_NOTIFIER,
				   sizeof (info->notifier), &info->notifier)
      != AMD_DBGAPI_STATUS_SUCCESS)
    {
      amd_dbgapi_process_detach (info->process_id);
      info->process_id = AMD_DBGAPI_PROCESS_NONE;
      warning (_("amd-dbgapi: could not retrieve process %d's notifier, GPU "
		 "debugging will not be available."), inf->pid);
      return;
    }

  amd_dbgapi_debug_printf ("process_id = %" PRIu64 ", notifier fd = %d",
			   info->process_id.handle, info->notifier);

  /* If GDB is attaching to a process that has the runtime loaded, there will
     already be a "runtime loaded" event available.  Consume it and push the
     target.  */
  dbgapi_notifier_handler (0, info);

  add_file_handler (info->notifier, dbgapi_notifier_handler, info,
		    "amd-dbgapi notifier");
}

static void maybe_reset_amd_dbgapi ();

/* Make the amd-dbgapi library detach from INF.

   Note that this us unrelated to the "detach" GDB concept / command.

   This undoes what attach_amd_dbgapi does.  */

static void
detach_amd_dbgapi (inferior *inf)
{
  AMD_DBGAPI_SCOPED_DEBUG_START_END ("inf num = %d", inf->num);

  auto *info = get_amd_dbgapi_inferior_info (inf);

  if (info->process_id == AMD_DBGAPI_PROCESS_NONE)
    return;

  info->runtime_state = AMD_DBGAPI_RUNTIME_STATE_UNLOADED;

  amd_dbgapi_status_t status = amd_dbgapi_process_detach (info->process_id);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    warning (_("amd-dbgapi: could not detach from process %d (%s)"),
	     inf->pid, get_status_string (status));

  gdb_assert (info->notifier != -1);
  delete_file_handler (info->notifier);

  /* This is a noop if the target is not pushed.  */
  inf->unpush_target (&the_amd_dbgapi_target);

  /* Delete the breakpoints that are still active.  */
  for (auto &&value : info->breakpoint_map)
    delete_breakpoint (value.second);

  /* Reset the amd_dbgapi_inferior_info.  */
  *info = amd_dbgapi_inferior_info (inf);

  maybe_reset_amd_dbgapi ();
}

void
amd_dbgapi_target::mourn_inferior ()
{
  detach_amd_dbgapi (current_inferior ());
  beneath ()->mourn_inferior ();
}

void
amd_dbgapi_target::detach (inferior *inf, int from_tty)
{
  /* We're about to resume the waves by detaching the dbgapi library from the
     inferior, so we need to remove all breakpoints that are still inserted.

     Breakpoints may still be inserted because the inferior may be running in
     non-stop mode, or because GDB changed the default setting to leave all
     breakpoints inserted in all-stop mode when all threads are stopped.  */
  remove_breakpoints_inf (inf);

  detach_amd_dbgapi (inf);
  beneath ()->detach (inf, from_tty);
}

void
amd_dbgapi_target::fetch_registers (struct regcache *regcache, int regno)
{
  if (!ptid_is_gpu (regcache->ptid ()))
    {
      beneath ()->fetch_registers (regcache, regno);
      return;
    }

  struct gdbarch *gdbarch = regcache->arch ();
  gdb_assert (is_amdgpu_arch (gdbarch));

  amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);
  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (regcache->ptid ());
  gdb_byte raw[AMDGPU_MAX_REGISTER_SIZE];
  amd_dbgapi_status_t status
    = amd_dbgapi_read_register (wave_id, tdep->register_ids[regno], 0,
				register_type (gdbarch, regno)->length (),
				raw);

  if (status == AMD_DBGAPI_STATUS_SUCCESS)
    regcache->raw_supply (regno, raw);
  else if (status != AMD_DBGAPI_STATUS_ERROR_REGISTER_NOT_AVAILABLE)
    warning (_("Couldn't read register %s (#%d) (%s)."),
	     gdbarch_register_name (gdbarch, regno), regno,
	     get_status_string (status));
}

void
amd_dbgapi_target::store_registers (struct regcache *regcache, int regno)
{
  if (!ptid_is_gpu (regcache->ptid ()))
    {
      beneath ()->store_registers (regcache, regno);
      return;
    }

  struct gdbarch *gdbarch = regcache->arch ();
  gdb_assert (is_amdgpu_arch (gdbarch));

  gdb_byte raw[AMDGPU_MAX_REGISTER_SIZE];
  regcache->raw_collect (regno, &raw);

  amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);

  /* If the register has read-only bits, invalidate the value in the regcache
     as the value actually written may differ.  */
  if (tdep->register_properties[regno]
      & AMD_DBGAPI_REGISTER_PROPERTY_READONLY_BITS)
    regcache->invalidate (regno);

  /* Invalidate all volatile registers if this register has the invalidate
     volatile property.  For example, writing to VCC may change the content
     of STATUS.VCCZ.  */
  if (tdep->register_properties[regno]
      & AMD_DBGAPI_REGISTER_PROPERTY_INVALIDATE_VOLATILE)
    {
      for (size_t r = 0; r < tdep->register_properties.size (); ++r)
	if (tdep->register_properties[r] & AMD_DBGAPI_REGISTER_PROPERTY_VOLATILE)
	  regcache->invalidate (r);
    }

  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (regcache->ptid ());
  amd_dbgapi_status_t status
    = amd_dbgapi_write_register (wave_id, tdep->register_ids[regno], 0,
				 register_type (gdbarch, regno)->length (),
				 raw);

  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    warning (_("Couldn't write register %s (#%d)."),
	     gdbarch_register_name (gdbarch, regno), regno);
}

struct gdbarch *
amd_dbgapi_target::thread_architecture (ptid_t ptid)
{
  if (!ptid_is_gpu (ptid))
    return beneath ()->thread_architecture (ptid);

  /* We can cache the gdbarch for a given wave_id (ptid::tid) because
     wave IDs are unique, and aren't reused.  */
  if (ptid.tid () == m_cached_arch_tid)
    return m_cached_arch;

  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (ptid);
  amd_dbgapi_architecture_id_t architecture_id;
  amd_dbgapi_status_t status;

  status = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_ARCHITECTURE,
				     sizeof (architecture_id),
				     &architecture_id);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("Couldn't get architecture for wave_%ld"), ptid.tid ());

  uint32_t elf_amdgpu_machine;
  status = amd_dbgapi_architecture_get_info
    (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_ELF_AMDGPU_MACHINE,
     sizeof (elf_amdgpu_machine), &elf_amdgpu_machine);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("Couldn't get elf_amdgpu_machine for architecture_%ld"),
	   architecture_id.handle);

  struct gdbarch_info info;
  info.bfd_arch_info = bfd_lookup_arch (bfd_arch_amdgcn, elf_amdgpu_machine);
  info.byte_order = BFD_ENDIAN_LITTLE;

  m_cached_arch_tid = ptid.tid ();
  m_cached_arch = gdbarch_find_by_info (info);
  if (m_cached_arch == nullptr)
    error (_("Couldn't get elf_amdgpu_machine (%#x)"), elf_amdgpu_machine);

  return m_cached_arch;
}

void
amd_dbgapi_target::thread_events (int enable)
{
  m_report_thread_events = enable;
  beneath ()->thread_events (enable);
}

void
amd_dbgapi_target::update_thread_list ()
{
  for (inferior *inf : all_inferiors ())
    {
      amd_dbgapi_process_id_t process_id
	= get_amd_dbgapi_process_id (inf);
      if (process_id == AMD_DBGAPI_PROCESS_NONE)
	{
	  /* The inferior may not be attached yet.  */
	  continue;
	}

      size_t count;
      amd_dbgapi_wave_id_t *wave_list;
      amd_dbgapi_changed_t changed;
      amd_dbgapi_status_t status
	= amd_dbgapi_process_wave_list (process_id, &count, &wave_list,
					&changed);
      if (status != AMD_DBGAPI_STATUS_SUCCESS)
	error (_("amd_dbgapi_wave_list failed (%s)"),
	       get_status_string (status));

      if (changed == AMD_DBGAPI_CHANGED_NO)
	continue;

      /* Create a set and free the wave list.  */
      std::set<ptid_t::tid_type> threads;
      for (size_t i = 0; i < count; ++i)
	threads.emplace (wave_list[i].handle);

      xfree (wave_list);

      /* Prune the wave_ids that already have a thread_info.  Any thread_info
	 which does not have a corresponding wave_id represents a wave which
	 is gone at this point and should be deleted.  */
      for (thread_info *tp : inf->threads_safe ())
	if (ptid_is_gpu (tp->ptid) && tp->state != THREAD_EXITED)
	  {
	    auto it = threads.find (tp->ptid.tid ());

	    if (it == threads.end ())
	      delete_thread (tp);
	    else
	      threads.erase (it);
	  }

      /* The wave_ids that are left require a new thread_info.  */
      for (ptid_t::tid_type tid : threads)
	{
	  ptid_t wave_ptid
	    = make_gpu_ptid (inf->pid, amd_dbgapi_wave_id_t {tid});

	  add_thread_silent (inf->process_target (), wave_ptid);
	  set_running (inf->process_target (), wave_ptid, true);
	  set_executing (inf->process_target (), wave_ptid, true);
	}
    }

  /* Give the beneath target a chance to do extra processing.  */
  this->beneath ()->update_thread_list ();
}

/* inferior_created observer.  */

static void
amd_dbgapi_target_inferior_created (inferior *inf)
{
  /* If the inferior is not running on the native target (e.g. it is running
     on a remote target), we don't want to deal with it.  */
  if (inf->process_target () != get_native_target ())
    return;

  attach_amd_dbgapi (inf);
}

/* inferior_execd observer.  */

static void
amd_dbgapi_inferior_execd (inferior *exec_inf, inferior *follow_inf)
{
  /* The inferior has EXEC'd and the process image has changed.  The dbgapi is
     attached to the old process image, so we need to detach and re-attach to
     the new process image.  */
  detach_amd_dbgapi (exec_inf);
  attach_amd_dbgapi (follow_inf);
}

/* inferior_forked observer.  */

static void
amd_dbgapi_inferior_forked (inferior *parent_inf, inferior *child_inf,
			    target_waitkind fork_kind)
{
  if (child_inf != nullptr  && fork_kind != TARGET_WAITKIND_VFORKED)
    {
      scoped_restore_current_thread restore_thread;
      switch_to_thread (*child_inf->threads ().begin ());
      attach_amd_dbgapi (child_inf);
    }
}

/* inferior_exit observer.

   This covers normal exits, but also detached inferiors (including detached
   fork parents).  */

static void
amd_dbgapi_inferior_exited (inferior *inf)
{
  detach_amd_dbgapi (inf);
}

/* inferior_pre_detach observer.  */

static void
amd_dbgapi_inferior_pre_detach (inferior *inf)
{
  /* We need to amd-dbgapi-detach before we ptrace-detach.  If the amd-dbgapi
     target isn't pushed, do that now.  If the amd-dbgapi target is pushed,
     we'll do it in amd_dbgapi_target::detach.  */
  if (!inf->target_is_pushed (&the_amd_dbgapi_target))
    detach_amd_dbgapi (inf);
}

/* get_os_pid callback.  */

static amd_dbgapi_status_t
amd_dbgapi_get_os_pid_callback
  (amd_dbgapi_client_process_id_t client_process_id, pid_t *pid)
{
  inferior *inf = reinterpret_cast<inferior *> (client_process_id);

  if (inf->pid == 0)
    return AMD_DBGAPI_STATUS_ERROR_PROCESS_EXITED;

  *pid = inf->pid;
  return AMD_DBGAPI_STATUS_SUCCESS;
}

/* insert_breakpoint callback.  */

static amd_dbgapi_status_t
amd_dbgapi_insert_breakpoint_callback
  (amd_dbgapi_client_process_id_t client_process_id,
   amd_dbgapi_global_address_t address,
   amd_dbgapi_breakpoint_id_t breakpoint_id)
{
  inferior *inf = reinterpret_cast<inferior *> (client_process_id);
  struct amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);

  auto it = info->breakpoint_map.find (breakpoint_id.handle);
  if (it != info->breakpoint_map.end ())
    return AMD_DBGAPI_STATUS_ERROR_INVALID_BREAKPOINT_ID;

  /* We need to find the address in the given inferior's program space.  */
  scoped_restore_current_thread restore_thread;
  switch_to_inferior_no_thread (inf);

  /* Create a new breakpoint.  */
  struct obj_section *section = find_pc_section (address);
  if (section == nullptr || section->objfile == nullptr)
    return AMD_DBGAPI_STATUS_ERROR;

  std::unique_ptr<breakpoint> bp_up
    (new amd_dbgapi_target_breakpoint (section->objfile->arch (), address));

  breakpoint *bp = install_breakpoint (true, std::move (bp_up), 1);

  info->breakpoint_map.emplace (breakpoint_id.handle, bp);
  return AMD_DBGAPI_STATUS_SUCCESS;
}

/* remove_breakpoint callback.  */

static amd_dbgapi_status_t
amd_dbgapi_remove_breakpoint_callback
  (amd_dbgapi_client_process_id_t client_process_id,
   amd_dbgapi_breakpoint_id_t breakpoint_id)
{
  inferior *inf = reinterpret_cast<inferior *> (client_process_id);
  struct amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);

  auto it = info->breakpoint_map.find (breakpoint_id.handle);
  if (it == info->breakpoint_map.end ())
    return AMD_DBGAPI_STATUS_ERROR_INVALID_BREAKPOINT_ID;

  delete_breakpoint (it->second);
  info->breakpoint_map.erase (it);

  return AMD_DBGAPI_STATUS_SUCCESS;
}

/* Style for some kinds of messages.  */

static cli_style_option fatal_error_style
  ("amd_dbgapi_fatal_error", ui_file_style::RED);
static cli_style_option warning_style
  ("amd_dbgapi_warning", ui_file_style::YELLOW);

/* BLACK + BOLD means dark gray.  */
static cli_style_option trace_style
  ("amd_dbgapi_trace", ui_file_style::BLACK, ui_file_style::BOLD);

/* log_message callback.  */

static void
amd_dbgapi_log_message_callback (amd_dbgapi_log_level_t level,
				 const char *message)
{
  gdb::optional<target_terminal::scoped_restore_terminal_state> tstate;

  if (target_supports_terminal_ours ())
    {
      tstate.emplace ();
      target_terminal::ours_for_output ();
    }

  /* Error and warning messages are meant to be printed to the user.  */
  if (level == AMD_DBGAPI_LOG_LEVEL_FATAL_ERROR
      || level == AMD_DBGAPI_LOG_LEVEL_WARNING)
    {
      begin_line ();
      ui_file_style style = (level == AMD_DBGAPI_LOG_LEVEL_FATAL_ERROR
			     ? fatal_error_style : warning_style).style ();
      gdb_printf (gdb_stderr, "%ps\n", styled_string (style, message));
      return;
    }

  /* Print other messages as debug logs.  TRACE and VERBOSE messages are
     very verbose, print them dark grey so it's easier to spot other messages
     through the flood.  */
  if (level >= AMD_DBGAPI_LOG_LEVEL_TRACE)
    {
      debug_prefixed_printf (amd_dbgapi_lib_debug_module (), nullptr, "%ps",
			     styled_string (trace_style.style (), message));
      return;
    }

  debug_prefixed_printf (amd_dbgapi_lib_debug_module (), nullptr, "%s",
			 message);
}

/* Callbacks passed to amd_dbgapi_initialize.  */

static amd_dbgapi_callbacks_t dbgapi_callbacks = {
  .allocate_memory = malloc,
  .deallocate_memory = free,
  .get_os_pid = amd_dbgapi_get_os_pid_callback,
  .insert_breakpoint = amd_dbgapi_insert_breakpoint_callback,
  .remove_breakpoint = amd_dbgapi_remove_breakpoint_callback,
  .log_message = amd_dbgapi_log_message_callback,
};

void
amd_dbgapi_target::close ()
{
  if (amd_dbgapi_async_event_handler != nullptr)
    delete_async_event_handler (&amd_dbgapi_async_event_handler);
}

/* List of set/show debug amd-dbgapi-lib commands.  */
struct cmd_list_element *set_debug_amd_dbgapi_lib_list;
struct cmd_list_element *show_debug_amd_dbgapi_lib_list;

/* Mapping from amd-dbgapi log level enum values to text.  */

static constexpr const char *debug_amd_dbgapi_lib_log_level_enums[] =
{
  /* [AMD_DBGAPI_LOG_LEVEL_NONE] = */ "off",
  /* [AMD_DBGAPI_LOG_LEVEL_FATAL_ERROR] = */ "error",
  /* [AMD_DBGAPI_LOG_LEVEL_WARNING] = */ "warning",
  /* [AMD_DBGAPI_LOG_LEVEL_INFO] = */ "info",
  /* [AMD_DBGAPI_LOG_LEVEL_TRACE] = */ "trace",
  /* [AMD_DBGAPI_LOG_LEVEL_VERBOSE] = */ "verbose",
  nullptr
};

/* Storage for "set debug amd-dbgapi-lib log-level".  */

static const char *debug_amd_dbgapi_lib_log_level
  = debug_amd_dbgapi_lib_log_level_enums[AMD_DBGAPI_LOG_LEVEL_WARNING];

/* Get the amd-dbgapi library log level requested by the user.  */

static amd_dbgapi_log_level_t
get_debug_amd_dbgapi_lib_log_level ()
{
  for (size_t pos = 0;
       debug_amd_dbgapi_lib_log_level_enums[pos] != nullptr;
       ++pos)
    if (debug_amd_dbgapi_lib_log_level
	== debug_amd_dbgapi_lib_log_level_enums[pos])
      return static_cast<amd_dbgapi_log_level_t> (pos);

  gdb_assert_not_reached ("invalid log level");
}

/* Callback for "set debug amd-dbgapi log-level", apply the selected log level
   to the library.  */

static void
set_debug_amd_dbgapi_lib_log_level (const char *args, int from_tty,
				    struct cmd_list_element *c)
{
  amd_dbgapi_set_log_level (get_debug_amd_dbgapi_lib_log_level ());
}

/* Callback for "show debug amd-dbgapi log-level".  */

static void
show_debug_amd_dbgapi_lib_log_level (struct ui_file *file, int from_tty,
				     struct cmd_list_element *c,
				     const char *value)
{
  gdb_printf (file, _("The amd-dbgapi library log level is %s.\n"), value);
}

/* If the amd-dbgapi library is not attached to any process, finalize and
   re-initialize it so that the handle ID numbers will all start from the
   beginning again.  This is only for convenience, not essential.  */

static void
maybe_reset_amd_dbgapi ()
{
  for (inferior *inf : all_non_exited_inferiors ())
    {
      amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);

      if (info->process_id != AMD_DBGAPI_PROCESS_NONE)
	return;
    }

  amd_dbgapi_status_t status = amd_dbgapi_finalize ();
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("amd-dbgapi failed to finalize (%s)"),
	   get_status_string (status));

  status = amd_dbgapi_initialize (&dbgapi_callbacks);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("amd-dbgapi failed to initialize (%s)"),
	   get_status_string (status));
}

extern initialize_file_ftype _initialize_amd_dbgapi_target;

void
_initialize_amd_dbgapi_target ()
{
  /* Make sure the loaded debugger library version is greater than or equal to
     the one used to build GDB.  */
  uint32_t major, minor, patch;
  amd_dbgapi_get_version (&major, &minor, &patch);
  if (major != AMD_DBGAPI_VERSION_MAJOR || minor < AMD_DBGAPI_VERSION_MINOR)
    error (_("amd-dbgapi library version mismatch, got %d.%d.%d, need %d.%d+"),
	   major, minor, patch, AMD_DBGAPI_VERSION_MAJOR,
	   AMD_DBGAPI_VERSION_MINOR);

  /* Initialize the AMD Debugger API.  */
  amd_dbgapi_status_t status = amd_dbgapi_initialize (&dbgapi_callbacks);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("amd-dbgapi failed to initialize (%s)"),
	   get_status_string (status));

  /* Set the initial log level.  */
  amd_dbgapi_set_log_level (get_debug_amd_dbgapi_lib_log_level ());

  /* Install observers.  */
  gdb::observers::inferior_created.attach
    (amd_dbgapi_target_inferior_created,
     amd_dbgapi_target_inferior_created_observer_token, "amd-dbgapi");
  gdb::observers::inferior_execd.attach (amd_dbgapi_inferior_execd, "amd-dbgapi");
  gdb::observers::inferior_forked.attach (amd_dbgapi_inferior_forked, "amd-dbgapi");
  gdb::observers::inferior_exit.attach (amd_dbgapi_inferior_exited, "amd-dbgapi");
  gdb::observers::inferior_pre_detach.attach (amd_dbgapi_inferior_pre_detach, "amd-dbgapi");

  add_basic_prefix_cmd ("amd-dbgapi-lib", no_class,
			_("Generic command for setting amd-dbgapi library "
			  "debugging flags."),
			&set_debug_amd_dbgapi_lib_list, 0, &setdebuglist);

  add_show_prefix_cmd ("amd-dbgapi-lib", no_class,
		       _("Generic command for showing amd-dbgapi library "
			 "debugging flags."),
		       &show_debug_amd_dbgapi_lib_list, 0, &showdebuglist);

  add_setshow_enum_cmd ("log-level", class_maintenance,
			debug_amd_dbgapi_lib_log_level_enums,
			&debug_amd_dbgapi_lib_log_level,
			_("Set the amd-dbgapi library log level."),
			_("Show the amd-dbgapi library log level."),
			_("off     == no logging is enabled\n"
			  "error   == fatal errors are reported\n"
			  "warning == fatal errors and warnings are reported\n"
			  "info    == fatal errors, warnings, and info "
			  "messages are reported\n"
			  "trace   == fatal errors, warnings, info, and "
			  "API tracing messages are reported\n"
			  "verbose == all messages are reported"),
			set_debug_amd_dbgapi_lib_log_level,
			show_debug_amd_dbgapi_lib_log_level,
			&set_debug_amd_dbgapi_lib_list,
			&show_debug_amd_dbgapi_lib_list);

  add_setshow_boolean_cmd ("amd-dbgapi", class_maintenance,
			   &debug_amd_dbgapi,
			   _("Set debugging of amd-dbgapi target."),
			   _("Show debugging of amd-dbgapi target."),
			   _("\
When on, print debug messages relating to the amd-dbgapi target."),
			   nullptr, nullptr,
			   &setdebuglist, &showdebuglist);
}
