1/* Target used to communicate with the AMD Debugger API.
2
3   Copyright (C) 2019-2024 Free Software Foundation, Inc.
4
5   This file is part of GDB.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20
21#include "amd-dbgapi-target.h"
22#include "amdgpu-tdep.h"
23#include "async-event.h"
24#include "cli/cli-cmds.h"
25#include "cli/cli-decode.h"
26#include "cli/cli-style.h"
27#include "inf-loop.h"
28#include "inferior.h"
29#include "objfiles.h"
30#include "observable.h"
31#include "registry.h"
32#include "solib.h"
33#include "target.h"
34
35/* When true, print debug messages relating to the amd-dbgapi target.  */
36
37static bool debug_amd_dbgapi = false;
38
39/* Make a copy of S styled in green.  */
40
41static std::string
42make_green (const char *s)
43{
44  cli_style_option style (nullptr, ui_file_style::GREEN);
45  string_file sf (true);
46  gdb_printf (&sf, "%ps", styled_string (style.style(), s));
47  return sf.release ();
48}
49
50/* Debug module names.  "amd-dbgapi" is for the target debug messages (this
51   file), whereas "amd-dbgapi-lib" is for logging messages output by the
52   amd-dbgapi library.  */
53
54static const char *amd_dbgapi_debug_module_unstyled = "amd-dbgapi";
55static const char *amd_dbgapi_lib_debug_module_unstyled
56  = "amd-dbgapi-lib";
57
58/* Styled variants of the above.  */
59
60static const std::string amd_dbgapi_debug_module_styled
61  = make_green (amd_dbgapi_debug_module_unstyled);
62static const std::string amd_dbgapi_lib_debug_module_styled
63  = make_green (amd_dbgapi_lib_debug_module_unstyled);
64
65/* Return the styled or unstyled variant of the amd-dbgapi module name,
66   depending on whether gdb_stdlog can emit colors.  */
67
68static const char *
69amd_dbgapi_debug_module ()
70{
71  if (gdb_stdlog->can_emit_style_escape ())
72    return amd_dbgapi_debug_module_styled.c_str ();
73  else
74    return amd_dbgapi_debug_module_unstyled;
75}
76
77/* Same as the above, but for the amd-dbgapi-lib module name.  */
78
79static const char *
80amd_dbgapi_lib_debug_module ()
81{
82  if (gdb_stdlog->can_emit_style_escape ())
83    return amd_dbgapi_lib_debug_module_styled.c_str ();
84  else
85    return amd_dbgapi_lib_debug_module_unstyled;
86}
87
88/* Print an amd-dbgapi debug statement.  */
89
90#define amd_dbgapi_debug_printf(fmt, ...) \
91  debug_prefixed_printf_cond (debug_amd_dbgapi, \
92			      amd_dbgapi_debug_module (), \
93			      fmt, ##__VA_ARGS__)
94
95/* Print amd-dbgapi start/end debug statements.  */
96
97#define AMD_DBGAPI_SCOPED_DEBUG_START_END(fmt, ...) \
98    scoped_debug_start_end (debug_amd_dbgapi, amd_dbgapi_debug_module (), \
99			    fmt, ##__VA_ARGS__)
100
101/* inferior_created observer token.  */
102
103static gdb::observers::token amd_dbgapi_target_inferior_created_observer_token;
104
105const gdb::observers::token &
106get_amd_dbgapi_target_inferior_created_observer_token ()
107{
108  return amd_dbgapi_target_inferior_created_observer_token;
109}
110
111/* A type holding coordinates, etc. info for a given wave.  */
112
113struct wave_coordinates
114{
115  /* The wave.  Set by the ctor.  */
116  amd_dbgapi_wave_id_t wave_id;
117
118  /* All these fields are initialized here to a value that is printed
119     as "?".  */
120  amd_dbgapi_dispatch_id_t dispatch_id = AMD_DBGAPI_DISPATCH_NONE;
121  amd_dbgapi_queue_id_t queue_id = AMD_DBGAPI_QUEUE_NONE;
122  amd_dbgapi_agent_id_t agent_id = AMD_DBGAPI_AGENT_NONE;
123  uint32_t group_ids[3] {UINT32_MAX, UINT32_MAX, UINT32_MAX};
124  uint32_t wave_in_group = UINT32_MAX;
125
126  explicit wave_coordinates (amd_dbgapi_wave_id_t wave_id)
127    : wave_id (wave_id)
128  {}
129
130  /* Return the target ID string for the wave this wave_coordinates is
131     for.  */
132  std::string to_string () const;
133
134  /* Pull out coordinates info from the amd-dbgapi library.  */
135  void fetch ();
136};
137
138/* A type holding info about a given wave.  */
139
140struct wave_info
141{
142  /* We cache the coordinates info because we need it after a wave
143     exits.  The wave's ID is here.  */
144  wave_coordinates coords;
145
146  /* The last resume_mode passed to amd_dbgapi_wave_resume for this
147     wave.  We track this because we are guaranteed to see a
148     WAVE_COMMAND_TERMINATED event if a stepping wave terminates, and
149     we need to know to not delete such a wave until we process that
150     event.  */
151  amd_dbgapi_resume_mode_t last_resume_mode = AMD_DBGAPI_RESUME_MODE_NORMAL;
152
153  /* Whether we've called amd_dbgapi_wave_stop for this wave and are
154     waiting for its stop event.  Similarly, we track this because
155     we're guaranteed to get a WAVE_COMMAND_TERMINATED event if the
156     wave terminates while being stopped.  */
157  bool stopping = false;
158
159  explicit wave_info (amd_dbgapi_wave_id_t wave_id)
160    : coords (wave_id)
161  {
162    coords.fetch ();
163  }
164};
165
166/* Big enough to hold the size of the largest register in bytes.  */
167#define AMDGPU_MAX_REGISTER_SIZE 256
168
169/* amd-dbgapi-specific inferior data.  */
170
171struct amd_dbgapi_inferior_info
172{
173  explicit amd_dbgapi_inferior_info (inferior *inf,
174				     bool precise_memory_requested = false)
175    : inf (inf)
176  {
177    precise_memory.requested = precise_memory_requested;
178  }
179
180  /* Backlink to inferior.  */
181  inferior *inf;
182
183  /* The amd_dbgapi_process_id for this inferior.  */
184  amd_dbgapi_process_id_t process_id = AMD_DBGAPI_PROCESS_NONE;
185
186  /* The amd_dbgapi_notifier_t for this inferior.  */
187  amd_dbgapi_notifier_t notifier = -1;
188
189  /* The status of the inferior's runtime support.  */
190  amd_dbgapi_runtime_state_t runtime_state = AMD_DBGAPI_RUNTIME_STATE_UNLOADED;
191
192  /* This value mirrors the current "forward progress needed" value for this
193     process in amd-dbgapi.  It is used to avoid unnecessary calls to
194     amd_dbgapi_process_set_progress, to reduce the noise in the logs.
195
196     Initialized to true, since that's the default in amd-dbgapi too.  */
197  bool forward_progress_required = true;
198
199  struct
200  {
201    /* Whether precise memory reporting is requested.  */
202    bool requested;
203
204    /* Whether precise memory was requested and successfully enabled by
205       dbgapi (it may not be available for the current hardware, for
206       instance).  */
207    bool enabled = false;
208  } precise_memory;
209
210  std::unordered_map<decltype (amd_dbgapi_breakpoint_id_t::handle),
211		     struct breakpoint *>
212    breakpoint_map;
213
214  /* List of pending events the amd-dbgapi target retrieved from the dbgapi.  */
215  std::list<std::pair<ptid_t, target_waitstatus>> wave_events;
216
217  /* Map of wave ID to wave_info.  We cache wave_info objects because
218     we need to access the info after the wave is gone, in the thread
219     exit nofication.  E.g.:
220	[AMDGPU Wave 1:4:1:1 (0,0,0)/0 exited]
221
222     wave_info objects are added when we first see the wave, and
223     removed from a thread_deleted observer.  */
224  std::unordered_map<decltype (amd_dbgapi_wave_id_t::handle), wave_info>
225    wave_info_map;
226};
227
228static amd_dbgapi_event_id_t process_event_queue
229  (amd_dbgapi_process_id_t process_id,
230   amd_dbgapi_event_kind_t until_event_kind = AMD_DBGAPI_EVENT_KIND_NONE);
231
232static const target_info amd_dbgapi_target_info = {
233  "amd-dbgapi",
234  N_("AMD Debugger API"),
235  N_("GPU debugging using the AMD Debugger API")
236};
237
238static amd_dbgapi_log_level_t get_debug_amd_dbgapi_lib_log_level ();
239
240struct amd_dbgapi_target final : public target_ops
241{
242  const target_info &
243  info () const override
244  {
245    return amd_dbgapi_target_info;
246  }
247  strata
248  stratum () const override
249  {
250    return arch_stratum;
251  }
252
253  void close () override;
254  void mourn_inferior () override;
255  void detach (inferior *inf, int from_tty) override;
256
257  void async (bool enable) override;
258
259  bool has_pending_events () override;
260  ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
261  void resume (ptid_t, int, enum gdb_signal) override;
262  void commit_resumed () override;
263  void stop (ptid_t ptid) override;
264
265  void fetch_registers (struct regcache *, int) override;
266  void store_registers (struct regcache *, int) override;
267
268  void update_thread_list () override;
269
270  struct gdbarch *thread_architecture (ptid_t) override;
271
272  void thread_events (int enable) override;
273
274  std::string pid_to_str (ptid_t ptid) override;
275
276  const char *thread_name (thread_info *tp) override;
277
278  const char *extra_thread_info (thread_info *tp) override;
279
280  bool thread_alive (ptid_t ptid) override;
281
282  enum target_xfer_status xfer_partial (enum target_object object,
283					const char *annex, gdb_byte *readbuf,
284					const gdb_byte *writebuf,
285					ULONGEST offset, ULONGEST len,
286					ULONGEST *xfered_len) override;
287
288  bool stopped_by_watchpoint () override;
289
290  bool stopped_by_sw_breakpoint () override;
291  bool stopped_by_hw_breakpoint () override;
292
293private:
294  /* True if we must report thread events.  */
295  bool m_report_thread_events = false;
296
297  /* Cache for the last value returned by thread_architecture.  */
298  gdbarch *m_cached_arch = nullptr;
299  ptid_t::tid_type m_cached_arch_tid = 0;
300};
301
302static struct amd_dbgapi_target the_amd_dbgapi_target;
303
304/* Per-inferior data key.  */
305
306static const registry<inferior>::key<amd_dbgapi_inferior_info>
307  amd_dbgapi_inferior_data;
308
309/* Fetch the amd_dbgapi_inferior_info data for the given inferior.  */
310
311static struct amd_dbgapi_inferior_info *
312get_amd_dbgapi_inferior_info (struct inferior *inferior)
313{
314  amd_dbgapi_inferior_info *info = amd_dbgapi_inferior_data.get (inferior);
315
316  if (info == nullptr)
317    info = amd_dbgapi_inferior_data.emplace (inferior, inferior);
318
319  return info;
320}
321
322/* The async event handler registered with the event loop, indicating that we
323   might have events to report to the core and that we'd like our wait method
324   to be called.
325
326   This is nullptr when async is disabled and non-nullptr when async is
327   enabled.
328
329   It is marked when a notifier fd tells us there's an event available.  The
330   callback triggers handle_inferior_event in order to pull the event from
331   amd-dbgapi and handle it.  */
332
333static async_event_handler *amd_dbgapi_async_event_handler = nullptr;
334
335std::string
336wave_coordinates::to_string () const
337{
338  std::string str = "AMDGPU Wave";
339
340  str += (agent_id != AMD_DBGAPI_AGENT_NONE
341	  ? string_printf (" %ld", agent_id.handle)
342	  : " ?");
343
344  str += (queue_id != AMD_DBGAPI_QUEUE_NONE
345	  ? string_printf (":%ld", queue_id.handle)
346	  : ":?");
347
348  str += (dispatch_id != AMD_DBGAPI_DISPATCH_NONE
349	  ? string_printf (":%ld", dispatch_id.handle)
350	  : ":?");
351
352  str += string_printf (":%ld", wave_id.handle);
353
354  str += (group_ids[0] != UINT32_MAX
355	  ? string_printf (" (%d,%d,%d)", group_ids[0], group_ids[1],
356			   group_ids[2])
357	  : " (?,?,?)");
358
359  str += (wave_in_group != UINT32_MAX
360	  ? string_printf ("/%d", wave_in_group)
361	  : "/?");
362
363  return str;
364}
365
366/* Read in wave_info for WAVE_ID.  */
367
368void
369wave_coordinates::fetch ()
370{
371  /* Any field that fails to be read is left with its in-class
372     initialized value, which is printed as "?".  */
373
374  amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_AGENT,
375			    sizeof (agent_id), &agent_id);
376  amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_QUEUE,
377			    sizeof (queue_id), &queue_id);
378  amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_DISPATCH,
379			    sizeof (dispatch_id), &dispatch_id);
380
381  amd_dbgapi_wave_get_info (wave_id,
382			    AMD_DBGAPI_WAVE_INFO_WORKGROUP_COORD,
383			    sizeof (group_ids), &group_ids);
384
385  amd_dbgapi_wave_get_info (wave_id,
386			    AMD_DBGAPI_WAVE_INFO_WAVE_NUMBER_IN_WORKGROUP,
387			    sizeof (wave_in_group), &wave_in_group);
388}
389
390/* Get the wave_info object for TP, from the wave_info map.  It is
391   assumed that the wave is in the map.  */
392
393static wave_info &
394get_thread_wave_info (thread_info *tp)
395{
396  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (tp->inf);
397  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (tp->ptid);
398
399  auto it = info->wave_info_map.find (wave_id.handle);
400  gdb_assert (it != info->wave_info_map.end ());
401
402  return it->second;
403}
404
405/* Clear our async event handler.  */
406
407static void
408async_event_handler_clear ()
409{
410  gdb_assert (amd_dbgapi_async_event_handler != nullptr);
411  clear_async_event_handler (amd_dbgapi_async_event_handler);
412}
413
414/* Mark our async event handler.  */
415
416static void
417async_event_handler_mark ()
418{
419  gdb_assert (amd_dbgapi_async_event_handler != nullptr);
420  mark_async_event_handler (amd_dbgapi_async_event_handler);
421}
422
423/* Set forward progress requirement to REQUIRE for all processes of PROC_TARGET
424   matching PTID.  */
425
426static void
427require_forward_progress (ptid_t ptid, process_stratum_target *proc_target,
428			  bool require)
429{
430  for (inferior *inf : all_inferiors (proc_target))
431    {
432      if (ptid != minus_one_ptid && inf->pid != ptid.pid ())
433	continue;
434
435      amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
436
437      if (info->process_id == AMD_DBGAPI_PROCESS_NONE)
438	continue;
439
440      /* Don't do unnecessary calls to amd-dbgapi to avoid polluting the logs.  */
441      if (info->forward_progress_required == require)
442	continue;
443
444      amd_dbgapi_status_t status
445	= amd_dbgapi_process_set_progress
446	    (info->process_id, (require
447				? AMD_DBGAPI_PROGRESS_NORMAL
448				: AMD_DBGAPI_PROGRESS_NO_FORWARD));
449      gdb_assert (status == AMD_DBGAPI_STATUS_SUCCESS);
450
451      info->forward_progress_required = require;
452
453      /* If ptid targets a single inferior and we have found it, no need to
454	 continue.  */
455      if (ptid != minus_one_ptid)
456	break;
457    }
458}
459
460/* See amd-dbgapi-target.h.  */
461
462amd_dbgapi_process_id_t
463get_amd_dbgapi_process_id (inferior *inf)
464{
465  return get_amd_dbgapi_inferior_info (inf)->process_id;
466}
467
468/* A breakpoint dbgapi wants us to insert, to handle shared library
469   loading/unloading.  */
470
471struct amd_dbgapi_target_breakpoint : public code_breakpoint
472{
473  amd_dbgapi_target_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
474    : code_breakpoint (gdbarch, bp_breakpoint)
475  {
476    symtab_and_line sal;
477    sal.pc = address;
478    sal.section = find_pc_overlay (sal.pc);
479    sal.pspace = current_program_space;
480    add_location (sal);
481
482    pspace = current_program_space;
483    disposition = disp_donttouch;
484  }
485
486  void re_set () override;
487  void check_status (struct bpstat *bs) override;
488};
489
490void
491amd_dbgapi_target_breakpoint::re_set ()
492{
493  /* Nothing.  */
494}
495
496void
497amd_dbgapi_target_breakpoint::check_status (struct bpstat *bs)
498{
499  struct inferior *inf = current_inferior ();
500  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
501  amd_dbgapi_status_t status;
502
503  bs->stop = 0;
504  bs->print_it = print_it_noop;
505
506  /* Find the address the breakpoint is set at.  */
507  auto match_breakpoint
508    = [bs] (const decltype (info->breakpoint_map)::value_type &value)
509      { return value.second == bs->breakpoint_at; };
510  auto it
511    = std::find_if (info->breakpoint_map.begin (), info->breakpoint_map.end (),
512		    match_breakpoint);
513
514  if (it == info->breakpoint_map.end ())
515    error (_("Could not find breakpoint_id for breakpoint at %s"),
516	   paddress (inf->arch (), bs->bp_location_at->address));
517
518  amd_dbgapi_breakpoint_id_t breakpoint_id { it->first };
519  amd_dbgapi_breakpoint_action_t action;
520
521  status = amd_dbgapi_report_breakpoint_hit
522    (breakpoint_id,
523     reinterpret_cast<amd_dbgapi_client_thread_id_t> (inferior_thread ()),
524     &action);
525
526  if (status != AMD_DBGAPI_STATUS_SUCCESS)
527    error (_("amd_dbgapi_report_breakpoint_hit failed for breakpoint %ld "
528	     "at %s (%s)"),
529	   breakpoint_id.handle, paddress (inf->arch (), bs->bp_location_at->address),
530	   get_status_string (status));
531
532  if (action == AMD_DBGAPI_BREAKPOINT_ACTION_RESUME)
533    return;
534
535  /* If the action is AMD_DBGAPI_BREAKPOINT_ACTION_HALT, we need to wait until
536     a breakpoint resume event for this breakpoint_id is seen.  */
537  amd_dbgapi_event_id_t resume_event_id
538    = process_event_queue (info->process_id,
539			   AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME);
540
541  /* We should always get a breakpoint_resume event after processing all
542     events generated by reporting the breakpoint hit.  */
543  gdb_assert (resume_event_id != AMD_DBGAPI_EVENT_NONE);
544
545  amd_dbgapi_breakpoint_id_t resume_breakpoint_id;
546  status = amd_dbgapi_event_get_info (resume_event_id,
547				      AMD_DBGAPI_EVENT_INFO_BREAKPOINT,
548				      sizeof (resume_breakpoint_id),
549				      &resume_breakpoint_id);
550
551  if (status != AMD_DBGAPI_STATUS_SUCCESS)
552    error (_("amd_dbgapi_event_get_info failed (%s)"), get_status_string (status));
553
554  /* The debugger API guarantees that [breakpoint_hit...resume_breakpoint]
555     sequences cannot interleave, so this breakpoint resume event must be
556     for our breakpoint_id.  */
557  if (resume_breakpoint_id != breakpoint_id)
558    error (_("breakpoint resume event is not for this breakpoint. "
559	      "Expected breakpoint_%ld, got breakpoint_%ld"),
560	   breakpoint_id.handle, resume_breakpoint_id.handle);
561
562  amd_dbgapi_event_processed (resume_event_id);
563}
564
565bool
566amd_dbgapi_target::thread_alive (ptid_t ptid)
567{
568  if (!ptid_is_gpu (ptid))
569    return beneath ()->thread_alive (ptid);
570
571  /* Check that the wave_id is valid.  */
572
573  amd_dbgapi_wave_state_t state;
574  amd_dbgapi_status_t status
575    = amd_dbgapi_wave_get_info (get_amd_dbgapi_wave_id (ptid),
576				AMD_DBGAPI_WAVE_INFO_STATE, sizeof (state),
577				&state);
578  return status == AMD_DBGAPI_STATUS_SUCCESS;
579}
580
581const char *
582amd_dbgapi_target::thread_name (thread_info *tp)
583{
584  if (!ptid_is_gpu (tp->ptid))
585    return beneath ()->thread_name (tp);
586
587  return nullptr;
588}
589
590std::string
591amd_dbgapi_target::pid_to_str (ptid_t ptid)
592{
593  if (!ptid_is_gpu (ptid))
594    return beneath ()->pid_to_str (ptid);
595
596  process_stratum_target *proc_target = current_inferior ()->process_target ();
597  inferior *inf = find_inferior_pid (proc_target, ptid.pid ());
598  gdb_assert (inf != nullptr);
599  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
600
601  auto wave_id = get_amd_dbgapi_wave_id (ptid);
602
603  auto it = info->wave_info_map.find (wave_id.handle);
604  if (it != info->wave_info_map.end ())
605    return it->second.coords.to_string ();
606
607  /* A wave we don't know about.  Shouldn't usually happen, but
608     asserting and bringing down the session is a bit too harsh.  Just
609     print all unknown info as "?"s.  */
610  return wave_coordinates (wave_id).to_string ();
611}
612
613const char *
614amd_dbgapi_target::extra_thread_info (thread_info *tp)
615{
616  if (!ptid_is_gpu (tp->ptid))
617    beneath ()->extra_thread_info (tp);
618
619  return nullptr;
620}
621
622target_xfer_status
623amd_dbgapi_target::xfer_partial (enum target_object object, const char *annex,
624			       gdb_byte *readbuf, const gdb_byte *writebuf,
625			       ULONGEST offset, ULONGEST requested_len,
626			       ULONGEST *xfered_len)
627{
628  std::optional<scoped_restore_current_thread> maybe_restore_thread;
629
630  if (!ptid_is_gpu (inferior_ptid))
631    return beneath ()->xfer_partial (object, annex, readbuf, writebuf, offset,
632				     requested_len, xfered_len);
633
634  gdb_assert (requested_len > 0);
635  gdb_assert (xfered_len != nullptr);
636
637  if (object != TARGET_OBJECT_MEMORY)
638    return TARGET_XFER_E_IO;
639
640  amd_dbgapi_process_id_t process_id
641    = get_amd_dbgapi_process_id (current_inferior ());
642  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (inferior_ptid);
643
644  size_t len = requested_len;
645  amd_dbgapi_status_t status;
646
647  if (readbuf != nullptr)
648    status = amd_dbgapi_read_memory (process_id, wave_id, 0,
649				     AMD_DBGAPI_ADDRESS_SPACE_GLOBAL,
650				     offset, &len, readbuf);
651  else
652    status = amd_dbgapi_write_memory (process_id, wave_id, 0,
653				      AMD_DBGAPI_ADDRESS_SPACE_GLOBAL,
654				      offset, &len, writebuf);
655
656  if (status != AMD_DBGAPI_STATUS_SUCCESS)
657    return TARGET_XFER_E_IO;
658
659  *xfered_len = len;
660  return TARGET_XFER_OK;
661}
662
663bool
664amd_dbgapi_target::stopped_by_watchpoint ()
665{
666  if (!ptid_is_gpu (inferior_ptid))
667    return beneath ()->stopped_by_watchpoint ();
668
669  return false;
670}
671
672void
673amd_dbgapi_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo)
674{
675  amd_dbgapi_debug_printf ("scope_ptid = %s", scope_ptid.to_string ().c_str ());
676
677  /* The amd_dbgapi_exceptions_t matching SIGNO will only be used if the
678     thread which is the target of the signal SIGNO is a GPU thread.  If so,
679     make sure that there is a corresponding amd_dbgapi_exceptions_t for SIGNO
680     before we try to resume any thread.  */
681  amd_dbgapi_exceptions_t exception = AMD_DBGAPI_EXCEPTION_NONE;
682  if (ptid_is_gpu (inferior_ptid))
683    {
684      switch (signo)
685	{
686	case GDB_SIGNAL_BUS:
687	  exception = AMD_DBGAPI_EXCEPTION_WAVE_APERTURE_VIOLATION;
688	  break;
689	case GDB_SIGNAL_SEGV:
690	  exception = AMD_DBGAPI_EXCEPTION_WAVE_MEMORY_VIOLATION;
691	  break;
692	case GDB_SIGNAL_ILL:
693	  exception = AMD_DBGAPI_EXCEPTION_WAVE_ILLEGAL_INSTRUCTION;
694	  break;
695	case GDB_SIGNAL_FPE:
696	  exception = AMD_DBGAPI_EXCEPTION_WAVE_MATH_ERROR;
697	  break;
698	case GDB_SIGNAL_ABRT:
699	  exception = AMD_DBGAPI_EXCEPTION_WAVE_ABORT;
700	  break;
701	case GDB_SIGNAL_TRAP:
702	  exception = AMD_DBGAPI_EXCEPTION_WAVE_TRAP;
703	  break;
704	case GDB_SIGNAL_0:
705	  exception = AMD_DBGAPI_EXCEPTION_NONE;
706	  break;
707	default:
708	  error (_("Resuming with signal %s is not supported by this agent."),
709		 gdb_signal_to_name (signo));
710	}
711    }
712
713  if (!ptid_is_gpu (inferior_ptid) || scope_ptid != inferior_ptid)
714    {
715      beneath ()->resume (scope_ptid, step, signo);
716
717      /* If the request is for a single thread, we are done.  */
718      if (scope_ptid == inferior_ptid)
719	return;
720    }
721
722  process_stratum_target *proc_target = current_inferior ()->process_target ();
723
724  /* Disable forward progress requirement.  */
725  require_forward_progress (scope_ptid, proc_target, false);
726
727  for (thread_info *thread : all_non_exited_threads (proc_target, scope_ptid))
728    {
729      if (!ptid_is_gpu (thread->ptid))
730	continue;
731
732      amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (thread->ptid);
733      amd_dbgapi_status_t status;
734
735      wave_info &wi = get_thread_wave_info (thread);
736      amd_dbgapi_resume_mode_t &resume_mode = wi.last_resume_mode;
737      amd_dbgapi_exceptions_t wave_exception;
738      if (thread->ptid == inferior_ptid)
739	{
740	  resume_mode = (step
741			 ? AMD_DBGAPI_RESUME_MODE_SINGLE_STEP
742			 : AMD_DBGAPI_RESUME_MODE_NORMAL);
743	  wave_exception = exception;
744	}
745      else
746	{
747	  resume_mode = AMD_DBGAPI_RESUME_MODE_NORMAL;
748	  wave_exception = AMD_DBGAPI_EXCEPTION_NONE;
749	}
750
751      status = amd_dbgapi_wave_resume (wave_id, resume_mode, wave_exception);
752      if (status != AMD_DBGAPI_STATUS_SUCCESS
753	  /* Ignore the error that wave is no longer valid as that could
754	     indicate that the process has exited.  GDB treats resuming a
755	     thread that no longer exists as being successful.  */
756	  && status != AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID)
757	error (_("wave_resume for wave_%ld failed (%s)"), wave_id.handle,
758	       get_status_string (status));
759
760      wi.stopping = false;
761    }
762}
763
764void
765amd_dbgapi_target::commit_resumed ()
766{
767  amd_dbgapi_debug_printf ("called");
768
769  beneath ()->commit_resumed ();
770
771  process_stratum_target *proc_target = current_inferior ()->process_target ();
772  require_forward_progress (minus_one_ptid, proc_target, true);
773}
774
775/* Return a string version of RESUME_MODE, for debug log purposes.  */
776
777static const char *
778resume_mode_to_string (amd_dbgapi_resume_mode_t resume_mode)
779{
780  switch (resume_mode)
781    {
782    case AMD_DBGAPI_RESUME_MODE_NORMAL:
783      return "normal";
784    case AMD_DBGAPI_RESUME_MODE_SINGLE_STEP:
785      return "step";
786    }
787  gdb_assert_not_reached ("invalid amd_dbgapi_resume_mode_t");
788}
789
790void
791amd_dbgapi_target::stop (ptid_t ptid)
792{
793  amd_dbgapi_debug_printf ("ptid = %s", ptid.to_string ().c_str ());
794
795  bool many_threads = ptid == minus_one_ptid || ptid.is_pid ();
796
797  if (!ptid_is_gpu (ptid) || many_threads)
798    {
799      beneath ()->stop (ptid);
800
801      /* The request is for a single thread, we are done.  */
802      if (!many_threads)
803	return;
804    }
805
806  auto stop_one_thread = [this] (thread_info *thread)
807    {
808      gdb_assert (thread != nullptr);
809
810      amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (thread->ptid);
811      amd_dbgapi_wave_state_t state;
812      amd_dbgapi_status_t status
813	= amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_STATE,
814				    sizeof (state), &state);
815      if (status == AMD_DBGAPI_STATUS_SUCCESS)
816	{
817	  /* If the wave is already known to be stopped then do nothing.  */
818	  if (state == AMD_DBGAPI_WAVE_STATE_STOP)
819	    return;
820
821	  status = amd_dbgapi_wave_stop (wave_id);
822	  if (status == AMD_DBGAPI_STATUS_SUCCESS)
823	    {
824	      wave_info &wi = get_thread_wave_info (thread);
825	      wi.stopping = true;
826	      return;
827	    }
828
829	  if (status != AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID)
830	    error (_("wave_stop for wave_%ld failed (%s)"), wave_id.handle,
831		   get_status_string (status));
832	}
833      else if (status != AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID)
834	error (_("wave_get_info for wave_%ld failed (%s)"), wave_id.handle,
835	       get_status_string (status));
836
837      /* The status is AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID.  The wave
838	 could have terminated since the last time the wave list was
839	 refreshed.  */
840
841      wave_info &wi = get_thread_wave_info (thread);
842      wi.stopping = true;
843
844      amd_dbgapi_debug_printf ("got AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID "
845			       "for wave_%ld, last_resume_mode=%s, "
846			       "report_thread_events=%d",
847			       wave_id.handle,
848			       resume_mode_to_string (wi.last_resume_mode),
849			       m_report_thread_events);
850
851      /* If the wave was stepping when it terminated, then it is
852	 guaranteed that we will see a WAVE_COMMAND_TERMINATED event
853	 for it.  Don't report a thread exit event or delete the
854	 thread yet, until we see such event.  */
855      if (wi.last_resume_mode == AMD_DBGAPI_RESUME_MODE_SINGLE_STEP)
856	return;
857
858      if (m_report_thread_events)
859	{
860	  get_amd_dbgapi_inferior_info (thread->inf)->wave_events.emplace_back
861	    (thread->ptid, target_waitstatus ().set_thread_exited (0));
862
863	  if (target_is_async_p ())
864	    async_event_handler_mark ();
865	}
866
867      delete_thread_silent (thread);
868    };
869
870  process_stratum_target *proc_target = current_inferior ()->process_target ();
871
872  /* Disable forward progress requirement.  */
873  require_forward_progress (ptid, proc_target, false);
874
875  if (!many_threads)
876    {
877      /* No need to iterate all non-exited threads if the request is to stop a
878	 specific thread.  */
879      stop_one_thread (proc_target->find_thread (ptid));
880      return;
881    }
882
883  for (auto *inf : all_inferiors (proc_target))
884    /* Use the threads_safe iterator since stop_one_thread may delete the
885       thread if it has exited.  */
886    for (auto *thread : inf->threads_safe ())
887      if (thread->state != THREAD_EXITED && thread->ptid.matches (ptid)
888	  && ptid_is_gpu (thread->ptid))
889	stop_one_thread (thread);
890}
891
892/* Callback for our async event handler.  */
893
894static void
895handle_target_event (gdb_client_data client_data)
896{
897  inferior_event_handler (INF_REG_EVENT);
898}
899
900struct scoped_amd_dbgapi_event_processed
901{
902  scoped_amd_dbgapi_event_processed (amd_dbgapi_event_id_t event_id)
903    : m_event_id (event_id)
904  {
905    gdb_assert (event_id != AMD_DBGAPI_EVENT_NONE);
906  }
907
908  ~scoped_amd_dbgapi_event_processed ()
909  {
910    amd_dbgapi_status_t status = amd_dbgapi_event_processed (m_event_id);
911    if (status != AMD_DBGAPI_STATUS_SUCCESS)
912      warning (_("Failed to acknowledge amd-dbgapi event %" PRIu64),
913	       m_event_id.handle);
914  }
915
916  DISABLE_COPY_AND_ASSIGN (scoped_amd_dbgapi_event_processed);
917
918private:
919  amd_dbgapi_event_id_t m_event_id;
920};
921
922/* Called when a dbgapi notifier fd is readable.  CLIENT_DATA is the
923   amd_dbgapi_inferior_info object corresponding to the notifier.  */
924
925static void
926dbgapi_notifier_handler (int err, gdb_client_data client_data)
927{
928  amd_dbgapi_inferior_info *info = (amd_dbgapi_inferior_info *) client_data;
929  int ret;
930
931  /* Drain the notifier pipe.  */
932  do
933    {
934      char buf;
935      ret = read (info->notifier, &buf, 1);
936    }
937  while (ret >= 0 || (ret == -1 && errno == EINTR));
938
939  if (info->inf->target_is_pushed (&the_amd_dbgapi_target))
940    {
941      /* The amd-dbgapi target is pushed: signal our async handler, the event
942	 will be consumed through our wait method.  */
943
944      async_event_handler_mark ();
945    }
946  else
947    {
948      /* The amd-dbgapi target is not pushed: if there's an event, the only
949	 expected one is one of the RUNTIME kind.  If the event tells us the
950	 inferior as activated the ROCm runtime, push the amd-dbgapi
951	 target.  */
952
953      amd_dbgapi_event_id_t event_id;
954      amd_dbgapi_event_kind_t event_kind;
955      amd_dbgapi_status_t status
956	= amd_dbgapi_process_next_pending_event (info->process_id, &event_id,
957						 &event_kind);
958      if (status != AMD_DBGAPI_STATUS_SUCCESS)
959	error (_("next_pending_event failed (%s)"), get_status_string (status));
960
961      if (event_id == AMD_DBGAPI_EVENT_NONE)
962	return;
963
964      gdb_assert (event_kind == AMD_DBGAPI_EVENT_KIND_RUNTIME);
965
966      scoped_amd_dbgapi_event_processed mark_event_processed (event_id);
967
968      amd_dbgapi_runtime_state_t runtime_state;
969      status = amd_dbgapi_event_get_info (event_id,
970					  AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE,
971					  sizeof (runtime_state),
972					  &runtime_state);
973      if (status != AMD_DBGAPI_STATUS_SUCCESS)
974	error (_("event_get_info for event_%ld failed (%s)"),
975	       event_id.handle, get_status_string (status));
976
977      switch (runtime_state)
978	{
979	case AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS:
980	  gdb_assert (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED);
981	  info->runtime_state = runtime_state;
982	  amd_dbgapi_debug_printf ("pushing amd-dbgapi target");
983	  info->inf->push_target (&the_amd_dbgapi_target);
984
985	  /* The underlying target will already be async if we are running, but not if
986	     we are attaching.  */
987	  if (info->inf->process_target ()->is_async_p ())
988	    {
989	      scoped_restore_current_thread restore_thread;
990	      switch_to_inferior_no_thread (info->inf);
991
992	      /* Make sure our async event handler is created.  */
993	      target_async (true);
994	    }
995	  break;
996
997	case AMD_DBGAPI_RUNTIME_STATE_UNLOADED:
998	  gdb_assert (info->runtime_state
999		      == AMD_DBGAPI_RUNTIME_STATE_LOADED_ERROR_RESTRICTION);
1000	  info->runtime_state = runtime_state;
1001	  break;
1002
1003	case AMD_DBGAPI_RUNTIME_STATE_LOADED_ERROR_RESTRICTION:
1004	  gdb_assert (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED);
1005	  info->runtime_state = runtime_state;
1006	  warning (_("amd-dbgapi: unable to enable GPU debugging "
1007		     "due to a restriction error"));
1008	  break;
1009	}
1010    }
1011}
1012
1013void
1014amd_dbgapi_target::async (bool enable)
1015{
1016  beneath ()->async (enable);
1017
1018  if (enable)
1019    {
1020      if (amd_dbgapi_async_event_handler != nullptr)
1021	{
1022	  /* Already enabled.  */
1023	  return;
1024	}
1025
1026      /* The library gives us one notifier file descriptor per inferior (even
1027	 the ones that have not yet loaded their runtime).  Register them
1028	 all with the event loop.  */
1029      process_stratum_target *proc_target
1030	= current_inferior ()->process_target ();
1031
1032      for (inferior *inf : all_non_exited_inferiors (proc_target))
1033	{
1034	  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
1035
1036	  if (info->notifier != -1)
1037	    add_file_handler (info->notifier, dbgapi_notifier_handler, info,
1038			      string_printf ("amd-dbgapi notifier for pid %d",
1039					     inf->pid));
1040	}
1041
1042      amd_dbgapi_async_event_handler
1043	= create_async_event_handler (handle_target_event, nullptr,
1044				      "amd-dbgapi");
1045
1046      /* There may be pending events to handle.  Tell the event loop to poll
1047	 them.  */
1048      async_event_handler_mark ();
1049    }
1050  else
1051    {
1052      if (amd_dbgapi_async_event_handler == nullptr)
1053	return;
1054
1055      for (inferior *inf : all_inferiors ())
1056	{
1057	  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
1058
1059	  if (info->notifier != -1)
1060	    delete_file_handler (info->notifier);
1061	}
1062
1063      delete_async_event_handler (&amd_dbgapi_async_event_handler);
1064    }
1065}
1066
1067/* Make a ptid for a GPU wave.  See comment on ptid_is_gpu for more details.  */
1068
1069static ptid_t
1070make_gpu_ptid (ptid_t::pid_type pid, amd_dbgapi_wave_id_t wave_id)
1071{
1072 return ptid_t (pid, 1, wave_id.handle);
1073}
1074
1075/* When a thread is deleted, remove its wave_info from the inferior's
1076   wave_info map.  */
1077
1078static void
1079amd_dbgapi_thread_deleted (thread_info *tp)
1080{
1081  if (tp->inf->target_at (arch_stratum) == &the_amd_dbgapi_target
1082      && ptid_is_gpu (tp->ptid))
1083    {
1084      amd_dbgapi_inferior_info *info = amd_dbgapi_inferior_data.get (tp->inf);
1085      auto wave_id = get_amd_dbgapi_wave_id (tp->ptid);
1086      auto it = info->wave_info_map.find (wave_id.handle);
1087      gdb_assert (it != info->wave_info_map.end ());
1088      info->wave_info_map.erase (it);
1089    }
1090}
1091
1092/* Register WAVE_PTID as a new thread in INF's thread list, and record
1093   its wave_info in the inferior's wave_info map.  */
1094
1095static thread_info *
1096add_gpu_thread (inferior *inf, ptid_t wave_ptid)
1097{
1098  process_stratum_target *proc_target = inf->process_target ();
1099  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
1100
1101  auto wave_id = get_amd_dbgapi_wave_id (wave_ptid);
1102
1103  if (!info->wave_info_map.try_emplace (wave_id.handle,
1104					wave_info (wave_id)).second)
1105    internal_error ("wave ID %ld already in map", wave_id.handle);
1106
1107  /* Create new GPU threads silently to avoid spamming the terminal
1108     with thousands of "[New Thread ...]" messages.  */
1109  thread_info *thread = add_thread_silent (proc_target, wave_ptid);
1110  set_running (proc_target, wave_ptid, true);
1111  set_executing (proc_target, wave_ptid, true);
1112  return thread;
1113}
1114
1115/* Process an event that was just pulled out of the amd-dbgapi library.  */
1116
1117static void
1118process_one_event (amd_dbgapi_event_id_t event_id,
1119		   amd_dbgapi_event_kind_t event_kind)
1120{
1121  /* Automatically mark this event processed when going out of scope.  */
1122  scoped_amd_dbgapi_event_processed mark_event_processed (event_id);
1123
1124  amd_dbgapi_process_id_t process_id;
1125  amd_dbgapi_status_t status
1126    = amd_dbgapi_event_get_info (event_id, AMD_DBGAPI_EVENT_INFO_PROCESS,
1127				 sizeof (process_id), &process_id);
1128  if (status != AMD_DBGAPI_STATUS_SUCCESS)
1129    error (_("event_get_info for event_%ld failed (%s)"), event_id.handle,
1130	   get_status_string (status));
1131
1132  amd_dbgapi_os_process_id_t pid;
1133  status = amd_dbgapi_process_get_info (process_id,
1134					AMD_DBGAPI_PROCESS_INFO_OS_ID,
1135					sizeof (pid), &pid);
1136  if (status != AMD_DBGAPI_STATUS_SUCCESS)
1137    error (_("process_get_info for process_%ld failed (%s)"),
1138	   process_id.handle, get_status_string (status));
1139
1140  auto *proc_target = current_inferior ()->process_target ();
1141  inferior *inf = find_inferior_pid (proc_target, pid);
1142  gdb_assert (inf != nullptr);
1143  amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
1144
1145  switch (event_kind)
1146    {
1147    case AMD_DBGAPI_EVENT_KIND_WAVE_COMMAND_TERMINATED:
1148    case AMD_DBGAPI_EVENT_KIND_WAVE_STOP:
1149      {
1150	amd_dbgapi_wave_id_t wave_id;
1151	status
1152	  = amd_dbgapi_event_get_info (event_id, AMD_DBGAPI_EVENT_INFO_WAVE,
1153				       sizeof (wave_id), &wave_id);
1154	if (status != AMD_DBGAPI_STATUS_SUCCESS)
1155	  error (_("event_get_info for event_%ld failed (%s)"),
1156		 event_id.handle, get_status_string (status));
1157
1158	ptid_t event_ptid = make_gpu_ptid (pid, wave_id);
1159	target_waitstatus ws;
1160
1161	amd_dbgapi_wave_stop_reasons_t stop_reason;
1162	status = amd_dbgapi_wave_get_info (wave_id,
1163					   AMD_DBGAPI_WAVE_INFO_STOP_REASON,
1164					   sizeof (stop_reason), &stop_reason);
1165	if (status == AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID
1166	    && event_kind == AMD_DBGAPI_EVENT_KIND_WAVE_COMMAND_TERMINATED)
1167	  ws.set_thread_exited (0);
1168	else if (status == AMD_DBGAPI_STATUS_SUCCESS)
1169	  {
1170	    if (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_APERTURE_VIOLATION)
1171	      ws.set_stopped (GDB_SIGNAL_BUS);
1172	    else if (stop_reason
1173		     & AMD_DBGAPI_WAVE_STOP_REASON_MEMORY_VIOLATION)
1174	      ws.set_stopped (GDB_SIGNAL_SEGV);
1175	    else if (stop_reason
1176		     & AMD_DBGAPI_WAVE_STOP_REASON_ILLEGAL_INSTRUCTION)
1177	      ws.set_stopped (GDB_SIGNAL_ILL);
1178	    else if (stop_reason
1179		     & (AMD_DBGAPI_WAVE_STOP_REASON_FP_INPUT_DENORMAL
1180			| AMD_DBGAPI_WAVE_STOP_REASON_FP_DIVIDE_BY_0
1181			| AMD_DBGAPI_WAVE_STOP_REASON_FP_OVERFLOW
1182			| AMD_DBGAPI_WAVE_STOP_REASON_FP_UNDERFLOW
1183			| AMD_DBGAPI_WAVE_STOP_REASON_FP_INEXACT
1184			| AMD_DBGAPI_WAVE_STOP_REASON_FP_INVALID_OPERATION
1185			| AMD_DBGAPI_WAVE_STOP_REASON_INT_DIVIDE_BY_0))
1186	      ws.set_stopped (GDB_SIGNAL_FPE);
1187	    else if (stop_reason
1188		     & (AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT
1189			| AMD_DBGAPI_WAVE_STOP_REASON_WATCHPOINT
1190			| AMD_DBGAPI_WAVE_STOP_REASON_SINGLE_STEP
1191			| AMD_DBGAPI_WAVE_STOP_REASON_DEBUG_TRAP
1192			| AMD_DBGAPI_WAVE_STOP_REASON_TRAP))
1193	      ws.set_stopped (GDB_SIGNAL_TRAP);
1194	    else if (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_ASSERT_TRAP)
1195	      ws.set_stopped (GDB_SIGNAL_ABRT);
1196	    else
1197	      ws.set_stopped (GDB_SIGNAL_0);
1198
1199	    thread_info *thread = proc_target->find_thread (event_ptid);
1200	    if (thread == nullptr)
1201	      thread = add_gpu_thread (inf, event_ptid);
1202
1203	    /* If the wave is stopped because of a software breakpoint, the
1204	       program counter needs to be adjusted so that it points to the
1205	       breakpoint instruction.  */
1206	    if ((stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT) != 0)
1207	      {
1208		regcache *regcache = get_thread_regcache (thread);
1209		gdbarch *gdbarch = regcache->arch ();
1210
1211		CORE_ADDR pc = regcache_read_pc (regcache);
1212		CORE_ADDR adjusted_pc
1213		  = pc - gdbarch_decr_pc_after_break (gdbarch);
1214
1215		if (adjusted_pc != pc)
1216		  regcache_write_pc (regcache, adjusted_pc);
1217	      }
1218	  }
1219	else
1220	  error (_("wave_get_info for wave_%ld failed (%s)"),
1221		 wave_id.handle, get_status_string (status));
1222
1223	info->wave_events.emplace_back (event_ptid, ws);
1224	break;
1225      }
1226
1227    case AMD_DBGAPI_EVENT_KIND_CODE_OBJECT_LIST_UPDATED:
1228      /* We get here when the following sequence of events happens:
1229
1230	   - the inferior hits the amd-dbgapi "r_brk" internal breakpoint
1231	   - amd_dbgapi_target_breakpoint::check_status calls
1232	     amd_dbgapi_report_breakpoint_hit, which queues an event of this
1233	     kind in dbgapi
1234	   - amd_dbgapi_target_breakpoint::check_status calls
1235	     process_event_queue, which pulls the event out of dbgapi, and
1236	     gets us here
1237
1238	 When amd_dbgapi_target_breakpoint::check_status is called, the current
1239	 inferior is the inferior that hit the breakpoint, which should still be
1240	 the case now.  */
1241      gdb_assert (inf == current_inferior ());
1242      handle_solib_event ();
1243      break;
1244
1245    case AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME:
1246      /* Breakpoint resume events should be handled by the breakpoint
1247	 action, and this code should not reach this.  */
1248      gdb_assert_not_reached ("unhandled event kind");
1249      break;
1250
1251    case AMD_DBGAPI_EVENT_KIND_RUNTIME:
1252      {
1253	amd_dbgapi_runtime_state_t runtime_state;
1254
1255	status = amd_dbgapi_event_get_info (event_id,
1256					    AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE,
1257					    sizeof (runtime_state),
1258					    &runtime_state);
1259	if (status != AMD_DBGAPI_STATUS_SUCCESS)
1260	  error (_("event_get_info for event_%ld failed (%s)"),
1261		 event_id.handle, get_status_string (status));
1262
1263	gdb_assert (runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED);
1264	gdb_assert
1265	  (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS);
1266
1267	info->runtime_state = runtime_state;
1268
1269	gdb_assert (inf->target_is_pushed (&the_amd_dbgapi_target));
1270	inf->unpush_target (&the_amd_dbgapi_target);
1271      }
1272      break;
1273
1274    default:
1275      error (_("event kind (%d) not supported"), event_kind);
1276    }
1277}
1278
1279/* Return a textual version of KIND.  */
1280
1281static const char *
1282event_kind_str (amd_dbgapi_event_kind_t kind)
1283{
1284  switch (kind)
1285    {
1286    case AMD_DBGAPI_EVENT_KIND_NONE:
1287      return "NONE";
1288
1289    case AMD_DBGAPI_EVENT_KIND_WAVE_STOP:
1290      return "WAVE_STOP";
1291
1292    case AMD_DBGAPI_EVENT_KIND_WAVE_COMMAND_TERMINATED:
1293      return "WAVE_COMMAND_TERMINATED";
1294
1295    case AMD_DBGAPI_EVENT_KIND_CODE_OBJECT_LIST_UPDATED:
1296      return "CODE_OBJECT_LIST_UPDATED";
1297
1298    case AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME:
1299      return "BREAKPOINT_RESUME";
1300
1301    case AMD_DBGAPI_EVENT_KIND_RUNTIME:
1302      return "RUNTIME";
1303
1304    case AMD_DBGAPI_EVENT_KIND_QUEUE_ERROR:
1305      return "QUEUE_ERROR";
1306    }
1307
1308  gdb_assert_not_reached ("unhandled amd_dbgapi_event_kind_t value");
1309}
1310
1311/* Drain the dbgapi event queue of a given process_id, or of all processes if
1312   process_id is AMD_DBGAPI_PROCESS_NONE.  Stop processing the events if an
1313   event of a given kind is requested and `process_id` is not
1314   AMD_DBGAPI_PROCESS_NONE.  Wave stop events that are not returned are queued
1315   into their inferior's amd_dbgapi_inferior_info pending wave events. */
1316
1317static amd_dbgapi_event_id_t
1318process_event_queue (amd_dbgapi_process_id_t process_id,
1319		     amd_dbgapi_event_kind_t until_event_kind)
1320{
1321  /* An event of a given type can only be requested from a single
1322     process_id.  */
1323  gdb_assert (until_event_kind == AMD_DBGAPI_EVENT_KIND_NONE
1324	      || process_id != AMD_DBGAPI_PROCESS_NONE);
1325
1326  while (true)
1327    {
1328      amd_dbgapi_event_id_t event_id;
1329      amd_dbgapi_event_kind_t event_kind;
1330
1331      amd_dbgapi_status_t status
1332	= amd_dbgapi_process_next_pending_event (process_id, &event_id,
1333						 &event_kind);
1334
1335      if (status != AMD_DBGAPI_STATUS_SUCCESS)
1336	error (_("next_pending_event failed (%s)"), get_status_string (status));
1337
1338      if (event_kind != AMD_DBGAPI_EVENT_KIND_NONE)
1339	amd_dbgapi_debug_printf ("Pulled event from dbgapi: "
1340				 "event_id.handle = %" PRIu64 ", "
1341				 "event_kind = %s",
1342				 event_id.handle,
1343				 event_kind_str (event_kind));
1344
1345      if (event_id == AMD_DBGAPI_EVENT_NONE || event_kind == until_event_kind)
1346	return event_id;
1347
1348      process_one_event (event_id, event_kind);
1349    }
1350}
1351
1352bool
1353amd_dbgapi_target::has_pending_events ()
1354{
1355  if (amd_dbgapi_async_event_handler != nullptr
1356      && async_event_handler_marked (amd_dbgapi_async_event_handler))
1357    return true;
1358
1359  return beneath ()->has_pending_events ();
1360}
1361
1362/* Pop one pending event from the per-inferior structures.
1363
1364   If PID is not -1, restrict the search to the inferior with that pid.  */
1365
1366static std::pair<ptid_t, target_waitstatus>
1367consume_one_event (int pid)
1368{
1369  auto *target = current_inferior ()->process_target ();
1370  struct amd_dbgapi_inferior_info *info = nullptr;
1371
1372  if (pid == -1)
1373    {
1374      for (inferior *inf : all_inferiors (target))
1375	{
1376	  info = get_amd_dbgapi_inferior_info (inf);
1377	  if (!info->wave_events.empty ())
1378	    break;
1379	}
1380
1381      gdb_assert (info != nullptr);
1382    }
1383  else
1384    {
1385      inferior *inf = find_inferior_pid (target, pid);
1386
1387      gdb_assert (inf != nullptr);
1388      info = get_amd_dbgapi_inferior_info (inf);
1389    }
1390
1391  if (info->wave_events.empty ())
1392    return { minus_one_ptid, {} };
1393
1394  auto event = info->wave_events.front ();
1395  info->wave_events.pop_front ();
1396
1397  return event;
1398}
1399
1400ptid_t
1401amd_dbgapi_target::wait (ptid_t ptid, struct target_waitstatus *ws,
1402			 target_wait_flags target_options)
1403{
1404  gdb_assert (!current_inferior ()->process_target ()->commit_resumed_state);
1405  gdb_assert (ptid == minus_one_ptid || ptid.is_pid ());
1406
1407  amd_dbgapi_debug_printf ("ptid = %s", ptid.to_string ().c_str ());
1408
1409  ptid_t event_ptid = beneath ()->wait (ptid, ws, target_options);
1410  if (event_ptid != minus_one_ptid)
1411    {
1412      if (ws->kind () == TARGET_WAITKIND_EXITED
1413	  || ws->kind () == TARGET_WAITKIND_SIGNALLED)
1414       {
1415	 /* This inferior has exited so drain its dbgapi event queue.  */
1416	 while (consume_one_event (event_ptid.pid ()).first
1417		!= minus_one_ptid)
1418	   ;
1419       }
1420      return event_ptid;
1421    }
1422
1423  gdb_assert (ws->kind () == TARGET_WAITKIND_NO_RESUMED
1424	      || ws->kind () == TARGET_WAITKIND_IGNORE);
1425
1426  /* Flush the async handler first.  */
1427  if (target_is_async_p ())
1428    async_event_handler_clear ();
1429
1430  /* There may be more events to process (either already in `wave_events` or
1431     that we need to fetch from dbgapi.  Mark the async event handler so that
1432     amd_dbgapi_target::wait gets called again and again, until it eventually
1433     returns minus_one_ptid.  */
1434  auto more_events = make_scope_exit ([] ()
1435    {
1436      if (target_is_async_p ())
1437	async_event_handler_mark ();
1438    });
1439
1440  auto *proc_target = current_inferior ()->process_target ();
1441
1442  /* Disable forward progress for the specified pid in ptid if it isn't
1443     minus_on_ptid, or all attached processes if ptid is minus_one_ptid.  */
1444  require_forward_progress (ptid, proc_target, false);
1445
1446  target_waitstatus gpu_waitstatus;
1447  std::tie (event_ptid, gpu_waitstatus) = consume_one_event (ptid.pid ());
1448  if (event_ptid == minus_one_ptid)
1449    {
1450      /* Drain the events for the current inferior from the amd_dbgapi and
1451	 preserve the ordering.  */
1452      auto info = get_amd_dbgapi_inferior_info (current_inferior ());
1453      process_event_queue (info->process_id, AMD_DBGAPI_EVENT_KIND_NONE);
1454
1455      std::tie (event_ptid, gpu_waitstatus) = consume_one_event (ptid.pid ());
1456      if (event_ptid == minus_one_ptid)
1457	{
1458	  /* If we requested a specific ptid, and nothing came out, assume
1459	     another ptid may have more events, otherwise, keep the
1460	     async_event_handler flushed.  */
1461	  if (ptid == minus_one_ptid)
1462	    more_events.release ();
1463
1464	  if (ws->kind () == TARGET_WAITKIND_NO_RESUMED)
1465	    {
1466	      /* We can't easily check that all GPU waves are stopped, and no
1467		 new waves can be created (the GPU has fixed function hardware
1468		 to create new threads), so even if the target beneath returns
1469		 waitkind_no_resumed, we have to report waitkind_ignore if GPU
1470		 debugging is enabled for at least one resumed inferior handled
1471		 by the amd-dbgapi target.  */
1472
1473	      for (inferior *inf : all_inferiors ())
1474		if (inf->target_at (arch_stratum) == &the_amd_dbgapi_target
1475		    && get_amd_dbgapi_inferior_info (inf)->runtime_state
1476			 == AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS)
1477		  {
1478		    ws->set_ignore ();
1479		    break;
1480		  }
1481	    }
1482
1483	  /* There are no events to report, return the target beneath's
1484	     waitstatus (either IGNORE or NO_RESUMED).  */
1485	  return minus_one_ptid;
1486	}
1487    }
1488
1489  *ws = gpu_waitstatus;
1490  return event_ptid;
1491}
1492
1493bool
1494amd_dbgapi_target::stopped_by_sw_breakpoint ()
1495{
1496  if (!ptid_is_gpu (inferior_ptid))
1497    return beneath ()->stopped_by_sw_breakpoint ();
1498
1499  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (inferior_ptid);
1500
1501  amd_dbgapi_wave_stop_reasons_t stop_reason;
1502  amd_dbgapi_status_t status
1503    = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_STOP_REASON,
1504				sizeof (stop_reason), &stop_reason);
1505
1506  if (status != AMD_DBGAPI_STATUS_SUCCESS)
1507    return false;
1508
1509  return (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT) != 0;
1510}
1511
1512bool
1513amd_dbgapi_target::stopped_by_hw_breakpoint ()
1514{
1515  if (!ptid_is_gpu (inferior_ptid))
1516    return beneath ()->stopped_by_hw_breakpoint ();
1517
1518  return false;
1519}
1520
1521/* Set the process' memory access reporting precision mode.
1522
1523   Warn if the requested mode is not supported on at least one agent in the
1524   process.
1525
1526   Error out if setting the requested mode failed for some other reason.  */
1527
1528static void
1529set_process_memory_precision (amd_dbgapi_inferior_info &info)
1530{
1531  auto mode = (info.precise_memory.requested
1532	       ? AMD_DBGAPI_MEMORY_PRECISION_PRECISE
1533	       : AMD_DBGAPI_MEMORY_PRECISION_NONE);
1534  amd_dbgapi_status_t status
1535    = amd_dbgapi_set_memory_precision (info.process_id, mode);
1536
1537  if (status == AMD_DBGAPI_STATUS_SUCCESS)
1538    info.precise_memory.enabled = info.precise_memory.requested;
1539  else if (status == AMD_DBGAPI_STATUS_ERROR_NOT_SUPPORTED)
1540    warning (_("AMDGPU precise memory access reporting could not be enabled."));
1541  else if (status != AMD_DBGAPI_STATUS_SUCCESS)
1542    error (_("amd_dbgapi_set_memory_precision failed (%s)"),
1543	   get_status_string (status));
1544}
1545
1546/* Make the amd-dbgapi library attach to the process behind INF.
1547
1548   Note that this is unrelated to the "attach" GDB concept / command.
1549
1550   By attaching to the process, we get a notifier fd that tells us when it
1551   activates the ROCm runtime and when there are subsequent debug events.  */
1552
1553static void
1554attach_amd_dbgapi (inferior *inf)
1555{
1556  AMD_DBGAPI_SCOPED_DEBUG_START_END ("inf num = %d", inf->num);
1557
1558  if (!target_can_async_p ())
1559    {
1560      warning (_("The amd-dbgapi target requires the target beneath to be "
1561		 "asynchronous, GPU debugging is disabled"));
1562      return;
1563    }
1564
1565  /* dbgapi can't attach to a vfork child (a process born from a vfork that
1566     hasn't exec'ed yet) while we are still attached to the parent.  It would
1567     not be useful for us to attach to vfork children anyway, because vfork
1568     children are very restricted in what they can do (see vfork(2)) and aren't
1569     going to launch some GPU programs that we need to debug.  To avoid this
1570     problem, we don't push the amd-dbgapi target / attach dbgapi in vfork
1571     children.  If a vfork child execs, we'll try enabling the amd-dbgapi target
1572     through the inferior_execd observer.  */
1573  if (inf->vfork_parent != nullptr)
1574    return;
1575
1576  auto *info = get_amd_dbgapi_inferior_info (inf);
1577
1578  /* Are we already attached?  */
1579  if (info->process_id != AMD_DBGAPI_PROCESS_NONE)
1580    {
1581      amd_dbgapi_debug_printf
1582	("already attached: process_id = %" PRIu64, info->process_id.handle);
1583      return;
1584    }
1585
1586  amd_dbgapi_status_t status
1587    = amd_dbgapi_process_attach
1588	(reinterpret_cast<amd_dbgapi_client_process_id_t> (inf),
1589	 &info->process_id);
1590  if (status == AMD_DBGAPI_STATUS_ERROR_RESTRICTION)
1591    {
1592      warning (_("amd-dbgapi: unable to enable GPU debugging due to a "
1593		 "restriction error"));
1594      return;
1595    }
1596  else if (status != AMD_DBGAPI_STATUS_SUCCESS)
1597    {
1598      warning (_("amd-dbgapi: could not attach to process %d (%s), GPU "
1599		 "debugging will not be available."), inf->pid,
1600	       get_status_string (status));
1601      return;
1602    }
1603
1604  if (amd_dbgapi_process_get_info (info->process_id,
1605				   AMD_DBGAPI_PROCESS_INFO_NOTIFIER,
1606				   sizeof (info->notifier), &info->notifier)
1607      != AMD_DBGAPI_STATUS_SUCCESS)
1608    {
1609      amd_dbgapi_process_detach (info->process_id);
1610      info->process_id = AMD_DBGAPI_PROCESS_NONE;
1611      warning (_("amd-dbgapi: could not retrieve process %d's notifier, GPU "
1612		 "debugging will not be available."), inf->pid);
1613      return;
1614    }
1615
1616  amd_dbgapi_debug_printf ("process_id = %" PRIu64 ", notifier fd = %d",
1617			   info->process_id.handle, info->notifier);
1618
1619  set_process_memory_precision (*info);
1620
1621  /* If GDB is attaching to a process that has the runtime loaded, there will
1622     already be a "runtime loaded" event available.  Consume it and push the
1623     target.  */
1624  dbgapi_notifier_handler (0, info);
1625
1626  add_file_handler (info->notifier, dbgapi_notifier_handler, info,
1627		    "amd-dbgapi notifier");
1628}
1629
1630static void maybe_reset_amd_dbgapi ();
1631
1632/* Make the amd-dbgapi library detach from INF.
1633
1634   Note that this us unrelated to the "detach" GDB concept / command.
1635
1636   This undoes what attach_amd_dbgapi does.  */
1637
1638static void
1639detach_amd_dbgapi (inferior *inf)
1640{
1641  AMD_DBGAPI_SCOPED_DEBUG_START_END ("inf num = %d", inf->num);
1642
1643  auto *info = get_amd_dbgapi_inferior_info (inf);
1644
1645  if (info->process_id == AMD_DBGAPI_PROCESS_NONE)
1646    return;
1647
1648  info->runtime_state = AMD_DBGAPI_RUNTIME_STATE_UNLOADED;
1649
1650  amd_dbgapi_status_t status = amd_dbgapi_process_detach (info->process_id);
1651  if (status != AMD_DBGAPI_STATUS_SUCCESS)
1652    warning (_("amd-dbgapi: could not detach from process %d (%s)"),
1653	     inf->pid, get_status_string (status));
1654
1655  gdb_assert (info->notifier != -1);
1656  delete_file_handler (info->notifier);
1657
1658  /* This is a noop if the target is not pushed.  */
1659  inf->unpush_target (&the_amd_dbgapi_target);
1660
1661  /* Delete the breakpoints that are still active.  */
1662  for (auto &&value : info->breakpoint_map)
1663    delete_breakpoint (value.second);
1664
1665  /* Reset the amd_dbgapi_inferior_info, except for precise_memory_mode.  */
1666  *info = amd_dbgapi_inferior_info (inf, info->precise_memory.requested);
1667
1668  maybe_reset_amd_dbgapi ();
1669}
1670
1671void
1672amd_dbgapi_target::mourn_inferior ()
1673{
1674  detach_amd_dbgapi (current_inferior ());
1675  beneath ()->mourn_inferior ();
1676}
1677
1678void
1679amd_dbgapi_target::detach (inferior *inf, int from_tty)
1680{
1681  /* We're about to resume the waves by detaching the dbgapi library from the
1682     inferior, so we need to remove all breakpoints that are still inserted.
1683
1684     Breakpoints may still be inserted because the inferior may be running in
1685     non-stop mode, or because GDB changed the default setting to leave all
1686     breakpoints inserted in all-stop mode when all threads are stopped.  */
1687  remove_breakpoints_inf (inf);
1688
1689  detach_amd_dbgapi (inf);
1690  beneath ()->detach (inf, from_tty);
1691}
1692
1693void
1694amd_dbgapi_target::fetch_registers (struct regcache *regcache, int regno)
1695{
1696  if (!ptid_is_gpu (regcache->ptid ()))
1697    {
1698      beneath ()->fetch_registers (regcache, regno);
1699      return;
1700    }
1701
1702  struct gdbarch *gdbarch = regcache->arch ();
1703  gdb_assert (is_amdgpu_arch (gdbarch));
1704
1705  amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);
1706  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (regcache->ptid ());
1707  gdb_byte raw[AMDGPU_MAX_REGISTER_SIZE];
1708  amd_dbgapi_status_t status
1709    = amd_dbgapi_read_register (wave_id, tdep->register_ids[regno], 0,
1710				register_type (gdbarch, regno)->length (),
1711				raw);
1712
1713  if (status == AMD_DBGAPI_STATUS_SUCCESS)
1714    regcache->raw_supply (regno, raw);
1715  else if (status != AMD_DBGAPI_STATUS_ERROR_REGISTER_NOT_AVAILABLE)
1716    warning (_("Couldn't read register %s (#%d) (%s)."),
1717	     gdbarch_register_name (gdbarch, regno), regno,
1718	     get_status_string (status));
1719}
1720
1721void
1722amd_dbgapi_target::store_registers (struct regcache *regcache, int regno)
1723{
1724  if (!ptid_is_gpu (regcache->ptid ()))
1725    {
1726      beneath ()->store_registers (regcache, regno);
1727      return;
1728    }
1729
1730  struct gdbarch *gdbarch = regcache->arch ();
1731  gdb_assert (is_amdgpu_arch (gdbarch));
1732
1733  gdb_byte raw[AMDGPU_MAX_REGISTER_SIZE];
1734  regcache->raw_collect (regno, &raw);
1735
1736  amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);
1737
1738  /* If the register has read-only bits, invalidate the value in the regcache
1739     as the value actually written may differ.  */
1740  if (tdep->register_properties[regno]
1741      & AMD_DBGAPI_REGISTER_PROPERTY_READONLY_BITS)
1742    regcache->invalidate (regno);
1743
1744  /* Invalidate all volatile registers if this register has the invalidate
1745     volatile property.  For example, writing to VCC may change the content
1746     of STATUS.VCCZ.  */
1747  if (tdep->register_properties[regno]
1748      & AMD_DBGAPI_REGISTER_PROPERTY_INVALIDATE_VOLATILE)
1749    {
1750      for (size_t r = 0; r < tdep->register_properties.size (); ++r)
1751	if (tdep->register_properties[r] & AMD_DBGAPI_REGISTER_PROPERTY_VOLATILE)
1752	  regcache->invalidate (r);
1753    }
1754
1755  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (regcache->ptid ());
1756  amd_dbgapi_status_t status
1757    = amd_dbgapi_write_register (wave_id, tdep->register_ids[regno], 0,
1758				 register_type (gdbarch, regno)->length (),
1759				 raw);
1760
1761  if (status != AMD_DBGAPI_STATUS_SUCCESS)
1762    warning (_("Couldn't write register %s (#%d)."),
1763	     gdbarch_register_name (gdbarch, regno), regno);
1764}
1765
1766struct gdbarch *
1767amd_dbgapi_target::thread_architecture (ptid_t ptid)
1768{
1769  if (!ptid_is_gpu (ptid))
1770    return beneath ()->thread_architecture (ptid);
1771
1772  /* We can cache the gdbarch for a given wave_id (ptid::tid) because
1773     wave IDs are unique, and aren't reused.  */
1774  if (ptid.tid () == m_cached_arch_tid)
1775    return m_cached_arch;
1776
1777  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (ptid);
1778  amd_dbgapi_architecture_id_t architecture_id;
1779  amd_dbgapi_status_t status;
1780
1781  status = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_ARCHITECTURE,
1782				     sizeof (architecture_id),
1783				     &architecture_id);
1784  if (status != AMD_DBGAPI_STATUS_SUCCESS)
1785    error (_("Couldn't get architecture for wave_%ld"), ptid.tid ());
1786
1787  uint32_t elf_amdgpu_machine;
1788  status = amd_dbgapi_architecture_get_info
1789    (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_ELF_AMDGPU_MACHINE,
1790     sizeof (elf_amdgpu_machine), &elf_amdgpu_machine);
1791  if (status != AMD_DBGAPI_STATUS_SUCCESS)
1792    error (_("Couldn't get elf_amdgpu_machine for architecture_%ld"),
1793	   architecture_id.handle);
1794
1795  struct gdbarch_info info;
1796  info.bfd_arch_info = bfd_lookup_arch (bfd_arch_amdgcn, elf_amdgpu_machine);
1797  info.byte_order = BFD_ENDIAN_LITTLE;
1798
1799  m_cached_arch_tid = ptid.tid ();
1800  m_cached_arch = gdbarch_find_by_info (info);
1801  if (m_cached_arch == nullptr)
1802    error (_("Couldn't get elf_amdgpu_machine (%#x)"), elf_amdgpu_machine);
1803
1804  return m_cached_arch;
1805}
1806
1807void
1808amd_dbgapi_target::thread_events (int enable)
1809{
1810  m_report_thread_events = enable;
1811  beneath ()->thread_events (enable);
1812}
1813
1814void
1815amd_dbgapi_target::update_thread_list ()
1816{
1817  for (inferior *inf : all_inferiors ())
1818    {
1819      amd_dbgapi_process_id_t process_id
1820	= get_amd_dbgapi_process_id (inf);
1821      if (process_id == AMD_DBGAPI_PROCESS_NONE)
1822	{
1823	  /* The inferior may not be attached yet.  */
1824	  continue;
1825	}
1826
1827      size_t count;
1828      amd_dbgapi_wave_id_t *wave_list;
1829      amd_dbgapi_changed_t changed;
1830      amd_dbgapi_status_t status
1831	= amd_dbgapi_process_wave_list (process_id, &count, &wave_list,
1832					&changed);
1833      if (status != AMD_DBGAPI_STATUS_SUCCESS)
1834	error (_("amd_dbgapi_wave_list failed (%s)"),
1835	       get_status_string (status));
1836
1837      if (changed == AMD_DBGAPI_CHANGED_NO)
1838	continue;
1839
1840      /* Create a set and free the wave list.  */
1841      std::set<ptid_t::tid_type> threads;
1842      for (size_t i = 0; i < count; ++i)
1843	threads.emplace (wave_list[i].handle);
1844
1845      xfree (wave_list);
1846
1847      /* Prune the wave_ids that already have a thread_info.  Any thread_info
1848	 which does not have a corresponding wave_id represents a wave which
1849	 is gone at this point and should be deleted.  */
1850      for (thread_info *tp : inf->threads_safe ())
1851	if (ptid_is_gpu (tp->ptid) && tp->state != THREAD_EXITED)
1852	  {
1853	    auto it = threads.find (tp->ptid.tid ());
1854
1855	    if (it == threads.end ())
1856	      {
1857		auto wave_id = get_amd_dbgapi_wave_id (tp->ptid);
1858		wave_info &wi = get_thread_wave_info (tp);
1859
1860		/* Waves that were stepping or in progress of being
1861		   stopped are guaranteed to report a
1862		   WAVE_COMMAND_TERMINATED event if they terminate.
1863		   Don't delete such threads until we see the
1864		   event.  */
1865		if (wi.last_resume_mode == AMD_DBGAPI_RESUME_MODE_SINGLE_STEP
1866		    || wi.stopping)
1867		  {
1868		    amd_dbgapi_debug_printf
1869		      ("wave_%ld disappeared, keeping it"
1870		       " (last_resume_mode=%s, stopping=%d)",
1871		       wave_id.handle,
1872		       resume_mode_to_string (wi.last_resume_mode),
1873		       wi.stopping);
1874		  }
1875		else
1876		  {
1877		    amd_dbgapi_debug_printf ("wave_%ld disappeared, deleting it",
1878					     wave_id.handle);
1879		    delete_thread_silent (tp);
1880		  }
1881	      }
1882	    else
1883	      threads.erase (it);
1884	  }
1885
1886      /* The wave_ids that are left require a new thread_info.  */
1887      for (ptid_t::tid_type tid : threads)
1888	{
1889	  ptid_t wave_ptid
1890	    = make_gpu_ptid (inf->pid, amd_dbgapi_wave_id_t {tid});
1891	  add_gpu_thread (inf, wave_ptid);
1892	}
1893    }
1894
1895  /* Give the beneath target a chance to do extra processing.  */
1896  this->beneath ()->update_thread_list ();
1897}
1898
1899/* inferior_created observer.  */
1900
1901static void
1902amd_dbgapi_target_inferior_created (inferior *inf)
1903{
1904  /* If the inferior is not running on the native target (e.g. it is running
1905     on a remote target), we don't want to deal with it.  */
1906  if (inf->process_target () != get_native_target ())
1907    return;
1908
1909  attach_amd_dbgapi (inf);
1910}
1911
1912/* Callback called when an inferior is cloned.  */
1913
1914static void
1915amd_dbgapi_target_inferior_cloned (inferior *original_inferior,
1916				   inferior *new_inferior)
1917{
1918  auto *orig_info = get_amd_dbgapi_inferior_info (original_inferior);
1919  auto *new_info = get_amd_dbgapi_inferior_info (new_inferior);
1920
1921  /* At this point, the process is not started.  Therefore it is sufficient to
1922     copy the precise memory request, it will be applied when the process
1923     starts.  */
1924  gdb_assert (new_info->process_id == AMD_DBGAPI_PROCESS_NONE);
1925  new_info->precise_memory.requested = orig_info->precise_memory.requested;
1926}
1927
1928/* inferior_execd observer.  */
1929
1930static void
1931amd_dbgapi_inferior_execd (inferior *exec_inf, inferior *follow_inf)
1932{
1933  /* The inferior has EXEC'd and the process image has changed.  The dbgapi is
1934     attached to the old process image, so we need to detach and re-attach to
1935     the new process image.  */
1936  detach_amd_dbgapi (exec_inf);
1937
1938  /* If using "follow-exec-mode new", carry over the precise-memory setting
1939     to the new inferior (otherwise, FOLLOW_INF and ORIG_INF point to the same
1940     inferior, so this is a no-op).  */
1941  get_amd_dbgapi_inferior_info (follow_inf)->precise_memory.requested
1942    = get_amd_dbgapi_inferior_info (exec_inf)->precise_memory.requested;
1943
1944  attach_amd_dbgapi (follow_inf);
1945}
1946
1947/* inferior_forked observer.  */
1948
1949static void
1950amd_dbgapi_inferior_forked (inferior *parent_inf, inferior *child_inf,
1951			    target_waitkind fork_kind)
1952{
1953  if (child_inf != nullptr)
1954    {
1955      /* Copy precise-memory requested value from parent to child.  */
1956      amd_dbgapi_inferior_info *parent_info
1957	= get_amd_dbgapi_inferior_info (parent_inf);
1958      amd_dbgapi_inferior_info *child_info
1959	= get_amd_dbgapi_inferior_info (child_inf);
1960      child_info->precise_memory.requested
1961	= parent_info->precise_memory.requested;
1962
1963      if (fork_kind != TARGET_WAITKIND_VFORKED)
1964	{
1965	  scoped_restore_current_thread restore_thread;
1966	  switch_to_thread (*child_inf->threads ().begin ());
1967	  attach_amd_dbgapi (child_inf);
1968	}
1969    }
1970}
1971
1972/* inferior_exit observer.
1973
1974   This covers normal exits, but also detached inferiors (including detached
1975   fork parents).  */
1976
1977static void
1978amd_dbgapi_inferior_exited (inferior *inf)
1979{
1980  detach_amd_dbgapi (inf);
1981}
1982
1983/* inferior_pre_detach observer.  */
1984
1985static void
1986amd_dbgapi_inferior_pre_detach (inferior *inf)
1987{
1988  /* We need to amd-dbgapi-detach before we ptrace-detach.  If the amd-dbgapi
1989     target isn't pushed, do that now.  If the amd-dbgapi target is pushed,
1990     we'll do it in amd_dbgapi_target::detach.  */
1991  if (!inf->target_is_pushed (&the_amd_dbgapi_target))
1992    detach_amd_dbgapi (inf);
1993}
1994
1995/* get_os_pid callback.  */
1996
1997static amd_dbgapi_status_t
1998amd_dbgapi_get_os_pid_callback
1999  (amd_dbgapi_client_process_id_t client_process_id, pid_t *pid)
2000{
2001  inferior *inf = reinterpret_cast<inferior *> (client_process_id);
2002
2003  if (inf->pid == 0)
2004    return AMD_DBGAPI_STATUS_ERROR_PROCESS_EXITED;
2005
2006  *pid = inf->pid;
2007  return AMD_DBGAPI_STATUS_SUCCESS;
2008}
2009
2010/* insert_breakpoint callback.  */
2011
2012static amd_dbgapi_status_t
2013amd_dbgapi_insert_breakpoint_callback
2014  (amd_dbgapi_client_process_id_t client_process_id,
2015   amd_dbgapi_global_address_t address,
2016   amd_dbgapi_breakpoint_id_t breakpoint_id)
2017{
2018  inferior *inf = reinterpret_cast<inferior *> (client_process_id);
2019  struct amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
2020
2021  auto it = info->breakpoint_map.find (breakpoint_id.handle);
2022  if (it != info->breakpoint_map.end ())
2023    return AMD_DBGAPI_STATUS_ERROR_INVALID_BREAKPOINT_ID;
2024
2025  /* We need to find the address in the given inferior's program space.  */
2026  scoped_restore_current_thread restore_thread;
2027  switch_to_inferior_no_thread (inf);
2028
2029  /* Create a new breakpoint.  */
2030  struct obj_section *section = find_pc_section (address);
2031  if (section == nullptr || section->objfile == nullptr)
2032    return AMD_DBGAPI_STATUS_ERROR;
2033
2034  std::unique_ptr<breakpoint> bp_up
2035    (new amd_dbgapi_target_breakpoint (section->objfile->arch (), address));
2036
2037  breakpoint *bp = install_breakpoint (true, std::move (bp_up), 1);
2038
2039  info->breakpoint_map.emplace (breakpoint_id.handle, bp);
2040  return AMD_DBGAPI_STATUS_SUCCESS;
2041}
2042
2043/* remove_breakpoint callback.  */
2044
2045static amd_dbgapi_status_t
2046amd_dbgapi_remove_breakpoint_callback
2047  (amd_dbgapi_client_process_id_t client_process_id,
2048   amd_dbgapi_breakpoint_id_t breakpoint_id)
2049{
2050  inferior *inf = reinterpret_cast<inferior *> (client_process_id);
2051  struct amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
2052
2053  auto it = info->breakpoint_map.find (breakpoint_id.handle);
2054  if (it == info->breakpoint_map.end ())
2055    return AMD_DBGAPI_STATUS_ERROR_INVALID_BREAKPOINT_ID;
2056
2057  delete_breakpoint (it->second);
2058  info->breakpoint_map.erase (it);
2059
2060  return AMD_DBGAPI_STATUS_SUCCESS;
2061}
2062
2063/* signal_received observer.  */
2064
2065static void
2066amd_dbgapi_target_signal_received (gdb_signal sig)
2067{
2068  amd_dbgapi_inferior_info *info
2069    = get_amd_dbgapi_inferior_info (current_inferior ());
2070
2071  if (info->process_id == AMD_DBGAPI_PROCESS_NONE)
2072    return;
2073
2074  if (!ptid_is_gpu (inferior_thread ()->ptid))
2075    return;
2076
2077  if (sig != GDB_SIGNAL_SEGV && sig != GDB_SIGNAL_BUS)
2078    return;
2079
2080  if (!info->precise_memory.enabled)
2081    gdb_printf (_("\
2082Warning: precise memory violation signal reporting is not enabled, reported\n\
2083location may not be accurate.  See \"show amdgpu precise-memory\".\n"));
2084}
2085
2086/* Style for some kinds of messages.  */
2087
2088static cli_style_option fatal_error_style
2089  ("amd_dbgapi_fatal_error", ui_file_style::RED);
2090static cli_style_option warning_style
2091  ("amd_dbgapi_warning", ui_file_style::YELLOW);
2092
2093/* BLACK + BOLD means dark gray.  */
2094static cli_style_option trace_style
2095  ("amd_dbgapi_trace", ui_file_style::BLACK, ui_file_style::BOLD);
2096
2097/* log_message callback.  */
2098
2099static void
2100amd_dbgapi_log_message_callback (amd_dbgapi_log_level_t level,
2101				 const char *message)
2102{
2103  std::optional<target_terminal::scoped_restore_terminal_state> tstate;
2104
2105  if (target_supports_terminal_ours ())
2106    {
2107      tstate.emplace ();
2108      target_terminal::ours_for_output ();
2109    }
2110
2111  /* Error and warning messages are meant to be printed to the user.  */
2112  if (level == AMD_DBGAPI_LOG_LEVEL_FATAL_ERROR
2113      || level == AMD_DBGAPI_LOG_LEVEL_WARNING)
2114    {
2115      begin_line ();
2116      ui_file_style style = (level == AMD_DBGAPI_LOG_LEVEL_FATAL_ERROR
2117			     ? fatal_error_style : warning_style).style ();
2118      gdb_printf (gdb_stderr, "%ps\n", styled_string (style, message));
2119      return;
2120    }
2121
2122  /* Print other messages as debug logs.  TRACE and VERBOSE messages are
2123     very verbose, print them dark grey so it's easier to spot other messages
2124     through the flood.  */
2125  if (level >= AMD_DBGAPI_LOG_LEVEL_TRACE)
2126    {
2127      debug_prefixed_printf (amd_dbgapi_lib_debug_module (), nullptr, "%ps",
2128			     styled_string (trace_style.style (), message));
2129      return;
2130    }
2131
2132  debug_prefixed_printf (amd_dbgapi_lib_debug_module (), nullptr, "%s",
2133			 message);
2134}
2135
2136/* Callbacks passed to amd_dbgapi_initialize.  */
2137
2138static amd_dbgapi_callbacks_t dbgapi_callbacks = {
2139  .allocate_memory = malloc,
2140  .deallocate_memory = free,
2141  .get_os_pid = amd_dbgapi_get_os_pid_callback,
2142  .insert_breakpoint = amd_dbgapi_insert_breakpoint_callback,
2143  .remove_breakpoint = amd_dbgapi_remove_breakpoint_callback,
2144  .log_message = amd_dbgapi_log_message_callback,
2145};
2146
2147void
2148amd_dbgapi_target::close ()
2149{
2150  if (amd_dbgapi_async_event_handler != nullptr)
2151    delete_async_event_handler (&amd_dbgapi_async_event_handler);
2152}
2153
2154/* Callback for "show amdgpu precise-memory".  */
2155
2156static void
2157show_precise_memory_mode (struct ui_file *file, int from_tty,
2158			  struct cmd_list_element *c, const char *value)
2159{
2160  amd_dbgapi_inferior_info *info
2161    = get_amd_dbgapi_inferior_info (current_inferior ());
2162
2163  gdb_printf (file,
2164	      _("AMDGPU precise memory access reporting is %s "
2165		"(currently %s).\n"),
2166	      info->precise_memory.requested ? "on" : "off",
2167	      info->precise_memory.enabled ? "enabled" : "disabled");
2168}
2169
2170/* Callback for "set amdgpu precise-memory".  */
2171
2172static void
2173set_precise_memory_mode (bool value)
2174{
2175  amd_dbgapi_inferior_info *info
2176    = get_amd_dbgapi_inferior_info (current_inferior ());
2177
2178  info->precise_memory.requested = value;
2179
2180  if (info->process_id != AMD_DBGAPI_PROCESS_NONE)
2181    set_process_memory_precision (*info);
2182}
2183
2184/* Return whether precise-memory is requested for the current inferior.  */
2185
2186static bool
2187get_precise_memory_mode ()
2188{
2189  amd_dbgapi_inferior_info *info
2190    = get_amd_dbgapi_inferior_info (current_inferior ());
2191
2192  return info->precise_memory.requested;
2193}
2194
2195/* List of set/show amdgpu commands.  */
2196struct cmd_list_element *set_amdgpu_list;
2197struct cmd_list_element *show_amdgpu_list;
2198
2199/* List of set/show debug amd-dbgapi-lib commands.  */
2200struct cmd_list_element *set_debug_amd_dbgapi_lib_list;
2201struct cmd_list_element *show_debug_amd_dbgapi_lib_list;
2202
2203/* Mapping from amd-dbgapi log level enum values to text.  */
2204
2205static constexpr const char *debug_amd_dbgapi_lib_log_level_enums[] =
2206{
2207  /* [AMD_DBGAPI_LOG_LEVEL_NONE] = */ "off",
2208  /* [AMD_DBGAPI_LOG_LEVEL_FATAL_ERROR] = */ "error",
2209  /* [AMD_DBGAPI_LOG_LEVEL_WARNING] = */ "warning",
2210  /* [AMD_DBGAPI_LOG_LEVEL_INFO] = */ "info",
2211  /* [AMD_DBGAPI_LOG_LEVEL_TRACE] = */ "trace",
2212  /* [AMD_DBGAPI_LOG_LEVEL_VERBOSE] = */ "verbose",
2213  nullptr
2214};
2215
2216/* Storage for "set debug amd-dbgapi-lib log-level".  */
2217
2218static const char *debug_amd_dbgapi_lib_log_level
2219  = debug_amd_dbgapi_lib_log_level_enums[AMD_DBGAPI_LOG_LEVEL_WARNING];
2220
2221/* Get the amd-dbgapi library log level requested by the user.  */
2222
2223static amd_dbgapi_log_level_t
2224get_debug_amd_dbgapi_lib_log_level ()
2225{
2226  for (size_t pos = 0;
2227       debug_amd_dbgapi_lib_log_level_enums[pos] != nullptr;
2228       ++pos)
2229    if (debug_amd_dbgapi_lib_log_level
2230	== debug_amd_dbgapi_lib_log_level_enums[pos])
2231      return static_cast<amd_dbgapi_log_level_t> (pos);
2232
2233  gdb_assert_not_reached ("invalid log level");
2234}
2235
2236/* Callback for "set debug amd-dbgapi log-level", apply the selected log level
2237   to the library.  */
2238
2239static void
2240set_debug_amd_dbgapi_lib_log_level (const char *args, int from_tty,
2241				    struct cmd_list_element *c)
2242{
2243  amd_dbgapi_set_log_level (get_debug_amd_dbgapi_lib_log_level ());
2244}
2245
2246/* Callback for "show debug amd-dbgapi log-level".  */
2247
2248static void
2249show_debug_amd_dbgapi_lib_log_level (struct ui_file *file, int from_tty,
2250				     struct cmd_list_element *c,
2251				     const char *value)
2252{
2253  gdb_printf (file, _("The amd-dbgapi library log level is %s.\n"), value);
2254}
2255
2256/* If the amd-dbgapi library is not attached to any process, finalize and
2257   re-initialize it so that the handle ID numbers will all start from the
2258   beginning again.  This is only for convenience, not essential.  */
2259
2260static void
2261maybe_reset_amd_dbgapi ()
2262{
2263  for (inferior *inf : all_non_exited_inferiors ())
2264    {
2265      amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
2266
2267      if (info->process_id != AMD_DBGAPI_PROCESS_NONE)
2268	return;
2269    }
2270
2271  amd_dbgapi_status_t status = amd_dbgapi_finalize ();
2272  if (status != AMD_DBGAPI_STATUS_SUCCESS)
2273    error (_("amd-dbgapi failed to finalize (%s)"),
2274	   get_status_string (status));
2275
2276  status = amd_dbgapi_initialize (&dbgapi_callbacks);
2277  if (status != AMD_DBGAPI_STATUS_SUCCESS)
2278    error (_("amd-dbgapi failed to initialize (%s)"),
2279	   get_status_string (status));
2280}
2281
2282extern initialize_file_ftype _initialize_amd_dbgapi_target;
2283
2284void
2285_initialize_amd_dbgapi_target ()
2286{
2287  /* Make sure the loaded debugger library version is greater than or equal to
2288     the one used to build GDB.  */
2289  uint32_t major, minor, patch;
2290  amd_dbgapi_get_version (&major, &minor, &patch);
2291  if (major != AMD_DBGAPI_VERSION_MAJOR || minor < AMD_DBGAPI_VERSION_MINOR)
2292    error (_("amd-dbgapi library version mismatch, got %d.%d.%d, need %d.%d+"),
2293	   major, minor, patch, AMD_DBGAPI_VERSION_MAJOR,
2294	   AMD_DBGAPI_VERSION_MINOR);
2295
2296  /* Initialize the AMD Debugger API.  */
2297  amd_dbgapi_status_t status = amd_dbgapi_initialize (&dbgapi_callbacks);
2298  if (status != AMD_DBGAPI_STATUS_SUCCESS)
2299    error (_("amd-dbgapi failed to initialize (%s)"),
2300	   get_status_string (status));
2301
2302  /* Set the initial log level.  */
2303  amd_dbgapi_set_log_level (get_debug_amd_dbgapi_lib_log_level ());
2304
2305  /* Install observers.  */
2306  gdb::observers::inferior_cloned.attach (amd_dbgapi_target_inferior_cloned,
2307					  "amd-dbgapi");
2308  gdb::observers::signal_received.attach (amd_dbgapi_target_signal_received,
2309					  "amd-dbgapi");
2310  gdb::observers::inferior_created.attach
2311    (amd_dbgapi_target_inferior_created,
2312     amd_dbgapi_target_inferior_created_observer_token, "amd-dbgapi");
2313  gdb::observers::inferior_execd.attach (amd_dbgapi_inferior_execd, "amd-dbgapi");
2314  gdb::observers::inferior_forked.attach (amd_dbgapi_inferior_forked, "amd-dbgapi");
2315  gdb::observers::inferior_exit.attach (amd_dbgapi_inferior_exited, "amd-dbgapi");
2316  gdb::observers::inferior_pre_detach.attach (amd_dbgapi_inferior_pre_detach, "amd-dbgapi");
2317  gdb::observers::thread_deleted.attach (amd_dbgapi_thread_deleted, "amd-dbgapi");
2318
2319  add_basic_prefix_cmd ("amdgpu", no_class,
2320			_("Generic command for setting amdgpu flags."),
2321			&set_amdgpu_list, 0, &setlist);
2322
2323  add_show_prefix_cmd ("amdgpu", no_class,
2324		       _("Generic command for showing amdgpu flags."),
2325		       &show_amdgpu_list, 0, &showlist);
2326
2327  add_setshow_boolean_cmd ("precise-memory", no_class,
2328			   _("Set precise-memory mode."),
2329			   _("Show precise-memory mode."), _("\
2330If on, precise memory reporting is enabled if/when the inferior is running.\n\
2331If off (default), precise memory reporting is disabled."),
2332			   set_precise_memory_mode,
2333			   get_precise_memory_mode,
2334			   show_precise_memory_mode,
2335			   &set_amdgpu_list, &show_amdgpu_list);
2336
2337  add_basic_prefix_cmd ("amd-dbgapi-lib", no_class,
2338			_("Generic command for setting amd-dbgapi library "
2339			  "debugging flags."),
2340			&set_debug_amd_dbgapi_lib_list, 0, &setdebuglist);
2341
2342  add_show_prefix_cmd ("amd-dbgapi-lib", no_class,
2343		       _("Generic command for showing amd-dbgapi library "
2344			 "debugging flags."),
2345		       &show_debug_amd_dbgapi_lib_list, 0, &showdebuglist);
2346
2347  add_setshow_enum_cmd ("log-level", class_maintenance,
2348			debug_amd_dbgapi_lib_log_level_enums,
2349			&debug_amd_dbgapi_lib_log_level,
2350			_("Set the amd-dbgapi library log level."),
2351			_("Show the amd-dbgapi library log level."),
2352			_("off     == no logging is enabled\n"
2353			  "error   == fatal errors are reported\n"
2354			  "warning == fatal errors and warnings are reported\n"
2355			  "info    == fatal errors, warnings, and info "
2356			  "messages are reported\n"
2357			  "trace   == fatal errors, warnings, info, and "
2358			  "API tracing messages are reported\n"
2359			  "verbose == all messages are reported"),
2360			set_debug_amd_dbgapi_lib_log_level,
2361			show_debug_amd_dbgapi_lib_log_level,
2362			&set_debug_amd_dbgapi_lib_list,
2363			&show_debug_amd_dbgapi_lib_list);
2364
2365  add_setshow_boolean_cmd ("amd-dbgapi", class_maintenance,
2366			   &debug_amd_dbgapi,
2367			   _("Set debugging of amd-dbgapi target."),
2368			   _("Show debugging of amd-dbgapi target."),
2369			   _("\
2370When on, print debug messages relating to the amd-dbgapi target."),
2371			   nullptr, nullptr,
2372			   &setdebuglist, &showdebuglist);
2373}
2374