1 /* Target-dependent code for the AMDGPU architectures.
3 Copyright (C) 2019-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
21 #include "amd-dbgapi-target.h"
22 #include "amdgpu-tdep.h"
23 #include "arch-utils.h"
25 #include "dwarf2/frame.h"
26 #include "frame-unwind.h"
28 #include "gdbsupport/selftest.h"
32 #include "observable.h"
34 #include "reggroups.h"
36 /* See amdgpu-tdep.h. */
39 is_amdgpu_arch (struct gdbarch
*arch
)
41 gdb_assert (arch
!= nullptr);
42 return gdbarch_bfd_arch_info (arch
)->arch
== bfd_arch_amdgcn
;
45 /* See amdgpu-tdep.h. */
48 get_amdgpu_gdbarch_tdep (gdbarch
*arch
)
50 return gdbarch_tdep
<amdgpu_gdbarch_tdep
> (arch
);
53 /* Dummy implementation of gdbarch_return_value_as_value. */
55 static return_value_convention
56 amdgpu_return_value_as_value (gdbarch
*arch
, value
*function
, type
*valtype
,
57 regcache
*regcache
, value
**read_value
,
58 const gdb_byte
*writebuf
)
60 gdb_assert_not_reached ("not implemented");
63 /* Return the name of register REGNUM. */
66 amdgpu_register_name (struct gdbarch
*gdbarch
, int regnum
)
68 /* The list of registers reported by amd-dbgapi for a given architecture
69 contains some duplicate names. For instance, there is an "exec" register
70 for waves in the wave32 mode and one for the waves in the wave64 mode.
71 However, at most one register with a given name is actually allocated for
72 a specific wave. If INFERIOR_PTID represents a GPU wave, we query
73 amd-dbgapi to know whether the requested register actually exists for the
74 current wave, so there won't be duplicates in the the register names we
77 But there are two known cases where INFERIOR_PTID doesn't represent a GPU
80 - The user does "set arch amdgcn:gfxNNN" followed with "maint print
82 - The "register_name" selftest
84 In these cases, we can't query amd-dbgapi to know whether we should hide
85 the register or not. The "register_name" selftest checks that there aren't
86 duplicates in the register names returned by the gdbarch, so if we simply
87 return all register names, that test will fail. The other simple option is
88 to never return a register name, which is what we do here. */
89 if (!ptid_is_gpu (inferior_ptid
))
92 amd_dbgapi_wave_id_t wave_id
= get_amd_dbgapi_wave_id (inferior_ptid
);
93 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
95 amd_dbgapi_register_exists_t register_exists
;
96 if (amd_dbgapi_wave_register_exists (wave_id
, tdep
->register_ids
[regnum
],
98 != AMD_DBGAPI_STATUS_SUCCESS
99 || register_exists
!= AMD_DBGAPI_REGISTER_PRESENT
)
102 return tdep
->register_names
[regnum
].c_str ();
105 /* Return the internal register number for the DWARF register number DWARF_REG.
107 Return -1 if there's no internal register mapping to DWARF_REG. */
110 amdgpu_dwarf_reg_to_regnum (struct gdbarch
*gdbarch
, int dwarf_reg
)
112 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
114 if (dwarf_reg
< tdep
->dwarf_regnum_to_gdb_regnum
.size ())
115 return tdep
->dwarf_regnum_to_gdb_regnum
[dwarf_reg
];
120 /* A hierarchy of classes to represent an amd-dbgapi register type. */
122 struct amd_dbgapi_register_type
135 amd_dbgapi_register_type (kind kind
, std::string lookup_name
)
136 : m_kind (kind
), m_lookup_name (std::move (lookup_name
))
139 virtual ~amd_dbgapi_register_type () = default;
141 /* Return the type's kind. */
145 /* Name to use for this type in the existing type map. */
146 const std::string
&lookup_name () const
147 { return m_lookup_name
; }
151 std::string m_lookup_name
;
154 using amd_dbgapi_register_type_up
= std::unique_ptr
<amd_dbgapi_register_type
>;
156 struct amd_dbgapi_register_type_integer
: public amd_dbgapi_register_type
158 amd_dbgapi_register_type_integer (bool is_unsigned
, unsigned int bit_size
)
159 : amd_dbgapi_register_type
161 string_printf ("%sint%d", is_unsigned
? "u" : "", bit_size
)),
162 m_is_unsigned (is_unsigned
),
163 m_bit_size (bit_size
)
166 bool is_unsigned () const
167 { return m_is_unsigned
; }
169 unsigned int bit_size () const
170 { return m_bit_size
; }
174 unsigned int m_bit_size
;
177 struct amd_dbgapi_register_type_float
: public amd_dbgapi_register_type
179 amd_dbgapi_register_type_float ()
180 : amd_dbgapi_register_type (kind::FLOAT
, "float")
184 struct amd_dbgapi_register_type_double
: public amd_dbgapi_register_type
186 amd_dbgapi_register_type_double ()
187 : amd_dbgapi_register_type (kind::DOUBLE
, "double")
191 struct amd_dbgapi_register_type_vector
: public amd_dbgapi_register_type
193 amd_dbgapi_register_type_vector (const amd_dbgapi_register_type
&element_type
,
195 : amd_dbgapi_register_type (kind::VECTOR
,
196 make_lookup_name (element_type
, count
)),
197 m_element_type (element_type
),
201 const amd_dbgapi_register_type
&element_type () const
202 { return m_element_type
; }
204 unsigned int count () const
207 static std::string make_lookup_name
208 (const amd_dbgapi_register_type
&element_type
, unsigned int count
)
210 return string_printf ("%s[%d]", element_type
.lookup_name ().c_str (),
215 const amd_dbgapi_register_type
&m_element_type
;
216 unsigned int m_count
;
219 struct amd_dbgapi_register_type_code_ptr
: public amd_dbgapi_register_type
221 amd_dbgapi_register_type_code_ptr ()
222 : amd_dbgapi_register_type (kind::CODE_PTR
, "void (*)()")
226 struct amd_dbgapi_register_type_flags
: public amd_dbgapi_register_type
231 unsigned int bit_pos_start
;
232 unsigned int bit_pos_end
;
233 const amd_dbgapi_register_type
*type
;
236 using container_type
= std::vector
<field
>;
237 using const_iterator_type
= container_type::const_iterator
;
239 amd_dbgapi_register_type_flags (unsigned int bit_size
, std::string_view name
)
240 : amd_dbgapi_register_type (kind::FLAGS
,
241 make_lookup_name (bit_size
, name
)),
242 m_bit_size (bit_size
),
243 m_name (std::move (name
))
246 unsigned int bit_size () const
247 { return m_bit_size
; }
249 void add_field (std::string name
, unsigned int bit_pos_start
,
250 unsigned int bit_pos_end
,
251 const amd_dbgapi_register_type
*type
)
253 m_fields
.push_back (field
{std::move (name
), bit_pos_start
,
257 container_type::size_type
size () const
258 { return m_fields
.size (); }
260 const field
&operator[] (container_type::size_type pos
) const
261 { return m_fields
[pos
]; }
263 const_iterator_type
begin () const
264 { return m_fields
.begin (); }
266 const_iterator_type
end () const
267 { return m_fields
.end (); }
269 const std::string
&name () const
272 static std::string
make_lookup_name (int bits
, std::string_view name
)
274 std::string res
= string_printf ("flags%d_t ", bits
);
275 res
.append (name
.data (), name
.size ());
280 unsigned int m_bit_size
;
281 container_type m_fields
;
285 using amd_dbgapi_register_type_flags_up
286 = std::unique_ptr
<amd_dbgapi_register_type_flags
>;
288 struct amd_dbgapi_register_type_enum
: public amd_dbgapi_register_type
296 using container_type
= std::vector
<enumerator
>;
297 using const_iterator_type
= container_type::const_iterator
;
299 amd_dbgapi_register_type_enum (std::string_view name
)
300 : amd_dbgapi_register_type (kind::ENUM
, make_lookup_name (name
)),
301 m_name (name
.data (), name
.length ())
304 void set_bit_size (int bit_size
)
305 { m_bit_size
= bit_size
; }
307 unsigned int bit_size () const
308 { return m_bit_size
; }
310 void add_enumerator (std::string name
, ULONGEST value
)
311 { m_enumerators
.push_back (enumerator
{std::move (name
), value
}); }
313 container_type::size_type
size () const
314 { return m_enumerators
.size (); }
316 const enumerator
&operator[] (container_type::size_type pos
) const
317 { return m_enumerators
[pos
]; }
319 const_iterator_type
begin () const
320 { return m_enumerators
.begin (); }
322 const_iterator_type
end () const
323 { return m_enumerators
.end (); }
325 const std::string
&name () const
328 static std::string
make_lookup_name (std::string_view name
)
330 std::string res
= "enum ";
331 res
.append (name
.data (), name
.length ());
336 unsigned int m_bit_size
= 32;
337 container_type m_enumerators
;
341 using amd_dbgapi_register_type_enum_up
342 = std::unique_ptr
<amd_dbgapi_register_type_enum
>;
344 /* Map type lookup names to types. */
345 using amd_dbgapi_register_type_map
346 = std::unordered_map
<std::string
, amd_dbgapi_register_type_up
>;
348 /* Parse S as a ULONGEST, raise an error on overflow. */
351 try_strtoulst (std::string_view s
)
354 ULONGEST value
= strtoulst (s
.data (), nullptr, 0);
356 error (_("Failed to parse integer."));
361 /* Shared regex bits. */
362 #define IDENTIFIER "[A-Za-z0-9_.]+"
364 #define WSOPT "[ \t]*"
366 static const amd_dbgapi_register_type
&
367 parse_amd_dbgapi_register_type (std::string_view type_name
,
368 amd_dbgapi_register_type_map
&type_map
);
371 /* parse_amd_dbgapi_register_type helper for enum types. */
374 parse_amd_dbgapi_register_type_enum_fields
375 (amd_dbgapi_register_type_enum
&enum_type
, std::string_view fields
)
377 compiled_regex
regex (/* name */
382 WSOPT
"(," WSOPT
")?",
384 _("Error in AMDGPU enum register type regex"));
385 regmatch_t matches
[4];
387 while (!fields
.empty ())
389 int res
= regex
.exec (fields
.data (), ARRAY_SIZE (matches
), matches
, 0);
390 if (res
== REG_NOMATCH
)
391 error (_("Failed to parse enum fields"));
393 auto sv_from_match
= [fields
] (const regmatch_t
&m
)
394 { return fields
.substr (m
.rm_so
, m
.rm_eo
- m
.rm_so
); };
396 std::string_view name
= sv_from_match (matches
[1]);
397 std::string_view value_str
= sv_from_match (matches
[2]);
398 ULONGEST value
= try_strtoulst (value_str
);
400 if (value
> std::numeric_limits
<uint32_t>::max ())
401 enum_type
.set_bit_size (64);
403 enum_type
.add_enumerator (std::string (name
), value
);
405 fields
= fields
.substr (matches
[0].rm_eo
);
409 /* parse_amd_dbgapi_register_type helper for flags types. */
412 parse_amd_dbgapi_register_type_flags_fields
413 (amd_dbgapi_register_type_flags
&flags_type
,
414 int bits
, std::string_view name
, std::string_view fields
,
415 amd_dbgapi_register_type_map
&type_map
)
417 gdb_assert (bits
== 32 || bits
== 64);
419 std::string regex_str
420 = string_printf (/* type */
421 "^(bool|uint%d_t|enum" WS IDENTIFIER WSOPT
"(\\{[^}]*})?)"
424 "(" IDENTIFIER
")" WSOPT
426 "@([0-9]+)(-[0-9]+)?" WSOPT
";" WSOPT
,
428 compiled_regex
regex (regex_str
.c_str (), REG_EXTENDED
,
429 _("Error in AMDGPU register type flags fields regex"));
430 regmatch_t matches
[6];
432 while (!fields
.empty ())
434 int res
= regex
.exec (fields
.data (), ARRAY_SIZE (matches
), matches
, 0);
435 if (res
== REG_NOMATCH
)
436 error (_("Failed to parse flags type fields string"));
438 auto sv_from_match
= [fields
] (const regmatch_t
&m
)
439 { return fields
.substr (m
.rm_so
, m
.rm_eo
- m
.rm_so
); };
441 std::string_view field_type_str
= sv_from_match (matches
[1]);
442 std::string_view field_name
= sv_from_match (matches
[3]);
443 std::string_view pos_begin_str
= sv_from_match (matches
[4]);
444 ULONGEST pos_begin
= try_strtoulst (pos_begin_str
);
446 if (field_type_str
== "bool")
447 flags_type
.add_field (std::string (field_name
), pos_begin
, pos_begin
,
451 if (matches
[5].rm_so
== -1)
452 error (_("Missing end bit position"));
454 std::string_view pos_end_str
= sv_from_match (matches
[5]);
455 ULONGEST pos_end
= try_strtoulst (pos_end_str
.substr (1));
456 const amd_dbgapi_register_type
&field_type
457 = parse_amd_dbgapi_register_type (field_type_str
, type_map
);
458 flags_type
.add_field (std::string (field_name
), pos_begin
, pos_end
,
462 fields
= fields
.substr (matches
[0].rm_eo
);
466 /* parse_amd_dbgapi_register_type helper for scalars. */
468 static const amd_dbgapi_register_type
&
469 parse_amd_dbgapi_register_type_scalar (std::string_view name
,
470 amd_dbgapi_register_type_map
&type_map
)
472 std::string
name_str (name
);
473 auto it
= type_map
.find (name_str
);
474 if (it
!= type_map
.end ())
476 enum amd_dbgapi_register_type::kind kind
= it
->second
->kind ();
477 if (kind
!= amd_dbgapi_register_type::kind::INTEGER
478 && kind
!= amd_dbgapi_register_type::kind::FLOAT
479 && kind
!= amd_dbgapi_register_type::kind::DOUBLE
480 && kind
!= amd_dbgapi_register_type::kind::CODE_PTR
)
481 error (_("type mismatch"));
486 amd_dbgapi_register_type_up type
;
487 if (name
== "int32_t")
488 type
.reset (new amd_dbgapi_register_type_integer (false, 32));
489 else if (name
== "uint32_t")
490 type
.reset (new amd_dbgapi_register_type_integer (true, 32));
491 else if (name
== "int64_t")
492 type
.reset (new amd_dbgapi_register_type_integer (false, 64));
493 else if (name
== "uint64_t")
494 type
.reset (new amd_dbgapi_register_type_integer (true, 64));
495 else if (name
== "float")
496 type
.reset (new amd_dbgapi_register_type_float ());
497 else if (name
== "double")
498 type
.reset (new amd_dbgapi_register_type_double ());
499 else if (name
== "void (*)()")
500 type
.reset (new amd_dbgapi_register_type_code_ptr ());
502 error (_("unknown type %s"), name_str
.c_str ());
504 auto insertion_pair
= type_map
.emplace (name
, std::move (type
));
505 return *insertion_pair
.first
->second
;
508 /* Parse an amd-dbgapi register type string into an amd_dbgapi_register_type
511 See the documentation of AMD_DBGAPI_REGISTER_INFO_TYPE in amd-dbgapi.h for
512 details about the format. */
514 static const amd_dbgapi_register_type
&
515 parse_amd_dbgapi_register_type (std::string_view type_str
,
516 amd_dbgapi_register_type_map
&type_map
)
518 size_t pos_open_bracket
= type_str
.find_last_of ('[');
519 auto sv_from_match
= [type_str
] (const regmatch_t
&m
)
520 { return type_str
.substr (m
.rm_so
, m
.rm_eo
- m
.rm_so
); };
522 if (pos_open_bracket
!= std::string_view::npos
)
525 std::string_view element_type_str
526 = type_str
.substr (0, pos_open_bracket
);
527 const amd_dbgapi_register_type
&element_type
528 = parse_amd_dbgapi_register_type (element_type_str
, type_map
);
530 size_t pos_close_bracket
= type_str
.find_last_of (']');
531 gdb_assert (pos_close_bracket
!= std::string_view::npos
);
532 std::string_view count_str_view
533 = type_str
.substr (pos_open_bracket
+ 1,
534 pos_close_bracket
- pos_open_bracket
);
535 std::string
count_str (count_str_view
);
536 unsigned int count
= std::stoul (count_str
);
538 std::string lookup_name
539 = amd_dbgapi_register_type_vector::make_lookup_name (element_type
, count
);
540 auto existing_type_it
= type_map
.find (lookup_name
);
541 if (existing_type_it
!= type_map
.end ())
543 gdb_assert (existing_type_it
->second
->kind ()
544 == amd_dbgapi_register_type::kind::VECTOR
);
545 return *existing_type_it
->second
;
548 amd_dbgapi_register_type_up type
549 (new amd_dbgapi_register_type_vector (element_type
, count
));
551 = type_map
.emplace (type
->lookup_name (), std::move (type
));
552 return *insertion_pair
.first
->second
;
555 if (type_str
.find ("flags32_t") == 0 || type_str
.find ("flags64_t") == 0)
557 /* Split 'type_str' into 4 tokens: "(type) (name) ({ (fields) })". */
558 compiled_regex
regex ("^(flags32_t|flags64_t)"
559 WS
"(" IDENTIFIER
")" WSOPT
560 "(\\{" WSOPT
"(.*)})?",
562 _("Error in AMDGPU register type regex"));
564 regmatch_t matches
[5];
565 int res
= regex
.exec (type_str
.data (), ARRAY_SIZE (matches
), matches
, 0);
566 if (res
== REG_NOMATCH
)
567 error (_("Failed to parse flags type string"));
569 std::string_view flags_keyword
= sv_from_match (matches
[1]);
570 unsigned int bit_size
= flags_keyword
== "flags32_t" ? 32 : 64;
571 std::string_view name
= sv_from_match (matches
[2]);
572 std::string lookup_name
573 = amd_dbgapi_register_type_flags::make_lookup_name (bit_size
, name
);
574 auto existing_type_it
= type_map
.find (lookup_name
);
576 if (matches
[3].rm_so
== -1)
578 /* No braces, lookup existing type. */
579 if (existing_type_it
== type_map
.end ())
580 error (_("reference to unknown type %s."),
581 std::string (name
).c_str ());
583 if (existing_type_it
->second
->kind ()
584 != amd_dbgapi_register_type::kind::FLAGS
)
585 error (_("type mismatch"));
587 return *existing_type_it
->second
;
591 /* With braces, it's a definition. */
592 if (existing_type_it
!= type_map
.end ())
593 error (_("re-definition of type %s."),
594 std::string (name
).c_str ());
596 amd_dbgapi_register_type_flags_up flags_type
597 (new amd_dbgapi_register_type_flags (bit_size
, name
));
598 std::string_view fields_without_braces
= sv_from_match (matches
[4]);
600 parse_amd_dbgapi_register_type_flags_fields
601 (*flags_type
, bit_size
, name
, fields_without_braces
, type_map
);
604 = type_map
.emplace (flags_type
->lookup_name (),
605 std::move (flags_type
));
606 return *insertion_pair
.first
->second
;
610 if (type_str
.find ("enum") == 0)
612 compiled_regex
regex ("^enum" WS
"(" IDENTIFIER
")" WSOPT
"(\\{" WSOPT
"([^}]*)})?",
614 _("Error in AMDGPU register type enum regex"));
616 /* Split 'type_name' into 3 tokens: "(name) ( { (fields) } )". */
617 regmatch_t matches
[4];
618 int res
= regex
.exec (type_str
.data (), ARRAY_SIZE (matches
), matches
, 0);
619 if (res
== REG_NOMATCH
)
620 error (_("Failed to parse flags type string"));
622 std::string_view name
= sv_from_match (matches
[1]);
624 std::string lookup_name
625 = amd_dbgapi_register_type_enum::make_lookup_name (name
);
626 auto existing_type_it
= type_map
.find (lookup_name
);
628 if (matches
[2].rm_so
== -1)
630 /* No braces, lookup existing type. */
631 if (existing_type_it
== type_map
.end ())
632 error (_("reference to unknown type %s"),
633 std::string (name
).c_str ());
635 if (existing_type_it
->second
->kind ()
636 != amd_dbgapi_register_type::kind::ENUM
)
637 error (_("type mismatch"));
639 return *existing_type_it
->second
;
643 /* With braces, it's a definition. */
644 if (existing_type_it
!= type_map
.end ())
645 error (_("re-definition of type %s"),
646 std::string (name
).c_str ());
648 amd_dbgapi_register_type_enum_up enum_type
649 (new amd_dbgapi_register_type_enum (name
));
650 std::string_view fields_without_braces
= sv_from_match (matches
[3]);
652 parse_amd_dbgapi_register_type_enum_fields
653 (*enum_type
, fields_without_braces
);
656 = type_map
.emplace (enum_type
->lookup_name (),
657 std::move (enum_type
));
658 return *insertion_pair
.first
->second
;
662 return parse_amd_dbgapi_register_type_scalar (type_str
, type_map
);
665 /* Convert an amd_dbgapi_register_type object to a GDB type. */
668 amd_dbgapi_register_type_to_gdb_type (const amd_dbgapi_register_type
&type
,
669 struct gdbarch
*gdbarch
)
671 switch (type
.kind ())
673 case amd_dbgapi_register_type::kind::INTEGER
:
675 const auto &integer_type
676 = gdb::checked_static_cast
<const amd_dbgapi_register_type_integer
&>
678 switch (integer_type
.bit_size ())
681 if (integer_type
.is_unsigned ())
682 return builtin_type (gdbarch
)->builtin_uint32
;
684 return builtin_type (gdbarch
)->builtin_int32
;
687 if (integer_type
.is_unsigned ())
688 return builtin_type (gdbarch
)->builtin_uint64
;
690 return builtin_type (gdbarch
)->builtin_int64
;
693 gdb_assert_not_reached ("invalid bit size");
697 case amd_dbgapi_register_type::kind::VECTOR
:
699 const auto &vector_type
700 = gdb::checked_static_cast
<const amd_dbgapi_register_type_vector
&>
702 struct type
*element_type
703 = amd_dbgapi_register_type_to_gdb_type (vector_type
.element_type (),
705 return init_vector_type (element_type
, vector_type
.count ());
708 case amd_dbgapi_register_type::kind::FLOAT
:
709 return builtin_type (gdbarch
)->builtin_float
;
711 case amd_dbgapi_register_type::kind::DOUBLE
:
712 return builtin_type (gdbarch
)->builtin_double
;
714 case amd_dbgapi_register_type::kind::CODE_PTR
:
715 return builtin_type (gdbarch
)->builtin_func_ptr
;
717 case amd_dbgapi_register_type::kind::FLAGS
:
719 const auto &flags_type
720 = gdb::checked_static_cast
<const amd_dbgapi_register_type_flags
&>
722 struct type
*gdb_type
723 = arch_flags_type (gdbarch
, flags_type
.name ().c_str (),
724 flags_type
.bit_size ());
726 for (const auto &field
: flags_type
)
728 if (field
.type
== nullptr)
730 gdb_assert (field
.bit_pos_start
== field
.bit_pos_end
);
731 append_flags_type_flag (gdb_type
, field
.bit_pos_start
,
732 field
.name
.c_str ());
736 struct type
*field_type
737 = amd_dbgapi_register_type_to_gdb_type (*field
.type
, gdbarch
);
738 gdb_assert (field_type
!= nullptr);
739 append_flags_type_field
740 (gdb_type
, field
.bit_pos_start
,
741 field
.bit_pos_end
- field
.bit_pos_start
+ 1,
742 field_type
, field
.name
.c_str ());
749 case amd_dbgapi_register_type::kind::ENUM
:
751 const auto &enum_type
752 = gdb::checked_static_cast
<const amd_dbgapi_register_type_enum
&>
754 struct type
*gdb_type
755 = (type_allocator (gdbarch
)
756 .new_type (TYPE_CODE_ENUM
, enum_type
.bit_size (),
757 enum_type
.name ().c_str ()));
759 gdb_type
->alloc_fields (enum_type
.size ());
760 gdb_type
->set_is_unsigned (true);
762 for (size_t i
= 0; i
< enum_type
.size (); ++i
)
764 const auto &field
= enum_type
[i
];
765 gdb_type
->field (i
).set_name (xstrdup (field
.name
.c_str ()));
766 gdb_type
->field (i
).set_loc_enumval (field
.value
);
773 gdb_assert_not_reached ("unhandled amd_dbgapi_register_type kind");
778 amdgpu_register_type (struct gdbarch
*gdbarch
, int regnum
)
780 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
782 if (tdep
->register_types
[regnum
] == nullptr)
784 /* This is done lazily (not at gdbarch initialization time), because it
785 requires access to builtin_type, which can't be used while the gdbarch
786 is not fully initialized. */
788 amd_dbgapi_status_t status
789 = amd_dbgapi_register_get_info (tdep
->register_ids
[regnum
],
790 AMD_DBGAPI_REGISTER_INFO_TYPE
,
791 sizeof (bytes
), &bytes
);
792 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
793 error (_("Failed to get register type from amd-dbgapi"));
795 gdb::unique_xmalloc_ptr
<char> bytes_holder (bytes
);
796 amd_dbgapi_register_type_map type_map
;
797 const amd_dbgapi_register_type
®ister_type
798 = parse_amd_dbgapi_register_type (bytes
, type_map
);
799 tdep
->register_types
[regnum
]
800 = amd_dbgapi_register_type_to_gdb_type (register_type
, gdbarch
);
801 gdb_assert (tdep
->register_types
[regnum
] != nullptr);
804 return tdep
->register_types
[regnum
];
808 amdgpu_register_reggroup_p (struct gdbarch
*gdbarch
, int regnum
,
809 const reggroup
*group
)
811 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
813 auto it
= tdep
->register_class_map
.find (group
->name ());
814 if (it
== tdep
->register_class_map
.end ())
815 return group
== all_reggroup
;
817 amd_dbgapi_register_class_state_t state
;
818 if (amd_dbgapi_register_is_in_register_class (it
->second
,
819 tdep
->register_ids
[regnum
],
821 != AMD_DBGAPI_STATUS_SUCCESS
)
822 return group
== all_reggroup
;
824 return (state
== AMD_DBGAPI_REGISTER_CLASS_STATE_MEMBER
825 || group
== all_reggroup
);
829 amdgpu_breakpoint_kind_from_pc (struct gdbarch
*gdbarch
, CORE_ADDR
*)
831 return get_amdgpu_gdbarch_tdep (gdbarch
)->breakpoint_instruction_size
;
834 static const gdb_byte
*
835 amdgpu_sw_breakpoint_from_kind (struct gdbarch
*gdbarch
, int kind
, int *size
)
838 return get_amdgpu_gdbarch_tdep (gdbarch
)->breakpoint_instruction_bytes
.get ();
841 struct amdgpu_frame_cache
847 static amdgpu_frame_cache
*
848 amdgpu_frame_cache (const frame_info_ptr
&this_frame
, void **this_cache
)
850 if (*this_cache
!= nullptr)
851 return (struct amdgpu_frame_cache
*) *this_cache
;
853 struct amdgpu_frame_cache
*cache
854 = FRAME_OBSTACK_ZALLOC (struct amdgpu_frame_cache
);
855 (*this_cache
) = cache
;
857 cache
->pc
= get_frame_func (this_frame
);
864 amdgpu_frame_this_id (const frame_info_ptr
&this_frame
, void **this_cache
,
867 struct amdgpu_frame_cache
*cache
868 = amdgpu_frame_cache (this_frame
, this_cache
);
870 if (get_frame_type (this_frame
) == INLINE_FRAME
)
871 (*this_id
) = frame_id_build (cache
->base
, cache
->pc
);
873 (*this_id
) = outer_frame_id
;
875 frame_debug_printf ("this_frame=%d, type=%d, this_id=%s",
876 frame_relative_level (this_frame
),
877 get_frame_type (this_frame
),
878 this_id
->to_string ().c_str ());
882 amdgpu_dummy_id (struct gdbarch
*gdbarch
, const frame_info_ptr
&this_frame
)
884 return frame_id_build (0, get_frame_pc (this_frame
));
887 static struct value
*
888 amdgpu_frame_prev_register (const frame_info_ptr
&this_frame
, void **this_cache
,
891 return frame_unwind_got_register (this_frame
, regnum
, regnum
);
894 static const frame_unwind amdgpu_frame_unwind
= {
897 default_frame_unwind_stop_reason
,
898 amdgpu_frame_this_id
,
899 amdgpu_frame_prev_register
,
901 default_frame_sniffer
,
907 print_insn_amdgpu (bfd_vma memaddr
, struct disassemble_info
*info
)
909 gdb_disassemble_info
*di
910 = static_cast<gdb_disassemble_info
*> (info
->application_data
);
912 /* Try to read at most INSTRUCTION_SIZE bytes. */
914 amd_dbgapi_size_t instruction_size
= gdbarch_max_insn_length (di
->arch ());
915 gdb::byte_vector
buffer (instruction_size
);
917 /* read_memory_func doesn't support partial reads, so if the read
918 fails, try one byte less, on and on until we manage to read
919 something. A case where this would happen is if we're trying to
920 read the last instruction at the end of a file section and that
921 instruction is smaller than the largest instruction. */
922 while (instruction_size
> 0)
924 int ret
= info
->read_memory_func (memaddr
, buffer
.data (),
925 instruction_size
, info
);
932 if (instruction_size
== 0)
934 info
->memory_error_func (-1, memaddr
, info
);
938 amd_dbgapi_architecture_id_t architecture_id
;
939 amd_dbgapi_status_t status
940 = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (di
->arch ())->mach
,
942 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
945 auto symbolizer
= [] (amd_dbgapi_symbolizer_id_t symbolizer_id
,
946 amd_dbgapi_global_address_t address
,
947 char **symbol_text
) -> amd_dbgapi_status_t
949 gdb_disassemble_info
*disasm_info
950 = reinterpret_cast<gdb_disassemble_info
*> (symbolizer_id
);
951 gdb_printing_disassembler
*disasm
952 = dynamic_cast<gdb_printing_disassembler
*> (disasm_info
);
953 gdb_assert (disasm
!= nullptr);
955 string_file
string (disasm
->stream ()->can_emit_style_escape ());
956 print_address (disasm
->arch (), address
, &string
);
957 *symbol_text
= xstrdup (string
.c_str ());
959 return AMD_DBGAPI_STATUS_SUCCESS
;
961 auto symbolizer_id
= reinterpret_cast<amd_dbgapi_symbolizer_id_t
> (di
);
962 char *instruction_text
= nullptr;
963 status
= amd_dbgapi_disassemble_instruction (architecture_id
, memaddr
,
969 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
972 status
= amd_dbgapi_architecture_get_info
974 AMD_DBGAPI_ARCHITECTURE_INFO_MINIMUM_INSTRUCTION_ALIGNMENT
,
975 sizeof (alignment
), &alignment
);
976 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
977 error (_("amd_dbgapi_architecture_get_info failed"));
979 info
->fprintf_func (di
, "<illegal instruction>");
981 /* Skip to the next valid instruction address. */
982 return align_up (memaddr
+ 1, alignment
) - memaddr
;
985 /* Print the instruction. */
986 info
->fprintf_func (di
, "%s", instruction_text
);
988 /* Free the memory allocated by the amd-dbgapi. */
989 xfree (instruction_text
);
991 return static_cast<int> (instruction_size
);
995 amdgpu_skip_prologue (struct gdbarch
*gdbarch
, CORE_ADDR start_pc
)
999 /* See if we can determine the end of the prologue via the symbol table.
1000 If so, then return either PC, or the PC after the prologue, whichever
1002 if (find_pc_partial_function (start_pc
, nullptr, &func_addr
, nullptr))
1004 CORE_ADDR post_prologue_pc
1005 = skip_prologue_using_sal (gdbarch
, func_addr
);
1006 struct compunit_symtab
*cust
= find_pc_compunit_symtab (func_addr
);
1008 /* Clang always emits a line note before the prologue and another
1009 one after. We trust clang to emit usable line notes. */
1010 if (post_prologue_pc
!= 0
1012 && cust
->producer () != nullptr
1013 && producer_is_llvm (cust
->producer ()))
1014 return std::max (start_pc
, post_prologue_pc
);
1021 amdgpu_supports_arch_info (const struct bfd_arch_info
*info
)
1023 amd_dbgapi_architecture_id_t architecture_id
;
1024 amd_dbgapi_status_t status
1025 = amd_dbgapi_get_architecture (info
->mach
, &architecture_id
);
1027 gdb_assert (status
!= AMD_DBGAPI_STATUS_ERROR_NOT_INITIALIZED
);
1028 return status
== AMD_DBGAPI_STATUS_SUCCESS
;
1031 static struct gdbarch
*
1032 amdgpu_gdbarch_init (struct gdbarch_info info
, struct gdbarch_list
*arches
)
1034 /* If there is already a candidate, use it. */
1035 arches
= gdbarch_list_lookup_by_info (arches
, &info
);
1036 if (arches
!= nullptr)
1037 return arches
->gdbarch
;
1039 /* Allocate space for the new architecture. */
1040 gdbarch_up gdbarch_u
1041 (gdbarch_alloc (&info
, gdbarch_tdep_up (new amdgpu_gdbarch_tdep
)));
1042 gdbarch
*gdbarch
= gdbarch_u
.get ();
1043 amdgpu_gdbarch_tdep
*tdep
= gdbarch_tdep
<amdgpu_gdbarch_tdep
> (gdbarch
);
1046 set_gdbarch_char_signed (gdbarch
, 0);
1047 set_gdbarch_ptr_bit (gdbarch
, 64);
1048 set_gdbarch_addr_bit (gdbarch
, 64);
1049 set_gdbarch_short_bit (gdbarch
, 16);
1050 set_gdbarch_int_bit (gdbarch
, 32);
1051 set_gdbarch_long_bit (gdbarch
, 64);
1052 set_gdbarch_long_long_bit (gdbarch
, 64);
1053 set_gdbarch_float_bit (gdbarch
, 32);
1054 set_gdbarch_double_bit (gdbarch
, 64);
1055 set_gdbarch_long_double_bit (gdbarch
, 128);
1056 set_gdbarch_half_format (gdbarch
, floatformats_ieee_half
);
1057 set_gdbarch_float_format (gdbarch
, floatformats_ieee_single
);
1058 set_gdbarch_double_format (gdbarch
, floatformats_ieee_double
);
1059 set_gdbarch_long_double_format (gdbarch
, floatformats_ieee_double
);
1061 /* Frame interpretation. */
1062 set_gdbarch_skip_prologue (gdbarch
, amdgpu_skip_prologue
);
1063 set_gdbarch_inner_than (gdbarch
, core_addr_greaterthan
);
1064 dwarf2_append_unwinders (gdbarch
);
1065 frame_unwind_append_unwinder (gdbarch
, &amdgpu_frame_unwind
);
1066 set_gdbarch_dummy_id (gdbarch
, amdgpu_dummy_id
);
1068 /* Registers and memory. */
1069 amd_dbgapi_architecture_id_t architecture_id
;
1070 amd_dbgapi_status_t status
1071 = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch
)->mach
,
1073 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1075 warning (_("Failed to get architecture from amd-dbgapi"));
1080 /* Add register groups. */
1081 size_t register_class_count
;
1082 amd_dbgapi_register_class_id_t
*register_class_ids
;
1083 status
= amd_dbgapi_architecture_register_class_list (architecture_id
,
1084 ®ister_class_count
,
1085 ®ister_class_ids
);
1086 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1088 warning (_("Failed to get register class list from amd-dbgapi"));
1092 gdb::unique_xmalloc_ptr
<amd_dbgapi_register_class_id_t
>
1093 register_class_ids_holder (register_class_ids
);
1095 for (size_t i
= 0; i
< register_class_count
; ++i
)
1098 status
= amd_dbgapi_architecture_register_class_get_info
1099 (register_class_ids
[i
], AMD_DBGAPI_REGISTER_CLASS_INFO_NAME
,
1100 sizeof (bytes
), &bytes
);
1101 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1103 warning (_("Failed to get register class name from amd-dbgapi"));
1107 gdb::unique_xmalloc_ptr
<char> name (bytes
);
1109 auto inserted
= tdep
->register_class_map
.emplace (name
.get (),
1110 register_class_ids
[i
]);
1111 gdb_assert (inserted
.second
);
1113 /* Avoid creating a user reggroup with the same name as some built-in
1114 reggroup, such as "general", "system", "vector", etc. */
1115 if (reggroup_find (gdbarch
, name
.get ()) != nullptr)
1118 /* Allocate the reggroup in the gdbarch. */
1120 (gdbarch
, reggroup_gdbarch_new (gdbarch
, name
.get (), USER_REGGROUP
));
1123 /* Add registers. */
1124 size_t register_count
;
1125 amd_dbgapi_register_id_t
*register_ids
;
1126 status
= amd_dbgapi_architecture_register_list (architecture_id
,
1129 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1131 warning (_("Failed to get register list from amd-dbgapi"));
1135 gdb::unique_xmalloc_ptr
<amd_dbgapi_register_id_t
> register_ids_holder
1138 tdep
->register_ids
.insert (tdep
->register_ids
.end (), ®ister_ids
[0],
1139 ®ister_ids
[register_count
]);
1141 tdep
->register_properties
.resize (register_count
,
1142 AMD_DBGAPI_REGISTER_PROPERTY_NONE
);
1143 for (size_t regnum
= 0; regnum
< register_count
; ++regnum
)
1145 auto ®ister_properties
= tdep
->register_properties
[regnum
];
1146 if (amd_dbgapi_register_get_info (register_ids
[regnum
],
1147 AMD_DBGAPI_REGISTER_INFO_PROPERTIES
,
1148 sizeof (register_properties
),
1149 ®ister_properties
)
1150 != AMD_DBGAPI_STATUS_SUCCESS
)
1152 warning (_("Failed to get register properties from amd-dbgapi"));
1157 set_gdbarch_num_regs (gdbarch
, register_count
);
1158 set_gdbarch_num_pseudo_regs (gdbarch
, 0);
1160 tdep
->register_names
.resize (register_count
);
1161 tdep
->register_types
.resize (register_count
);
1162 for (size_t i
= 0; i
< register_count
; ++i
)
1164 /* Set amd-dbgapi register id -> gdb regnum mapping. */
1165 tdep
->regnum_map
.emplace (tdep
->register_ids
[i
], i
);
1167 /* Get register name. */
1169 status
= amd_dbgapi_register_get_info (tdep
->register_ids
[i
],
1170 AMD_DBGAPI_REGISTER_INFO_NAME
,
1171 sizeof (bytes
), &bytes
);
1172 if (status
== AMD_DBGAPI_STATUS_SUCCESS
)
1174 tdep
->register_names
[i
] = bytes
;
1178 /* Get register DWARF number. */
1180 status
= amd_dbgapi_register_get_info (tdep
->register_ids
[i
],
1181 AMD_DBGAPI_REGISTER_INFO_DWARF
,
1182 sizeof (dwarf_num
), &dwarf_num
);
1183 if (status
== AMD_DBGAPI_STATUS_SUCCESS
)
1185 if (dwarf_num
>= tdep
->dwarf_regnum_to_gdb_regnum
.size ())
1186 tdep
->dwarf_regnum_to_gdb_regnum
.resize (dwarf_num
+ 1, -1);
1188 tdep
->dwarf_regnum_to_gdb_regnum
[dwarf_num
] = i
;
1192 amd_dbgapi_register_id_t pc_register_id
;
1193 status
= amd_dbgapi_architecture_get_info
1194 (architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_PC_REGISTER
,
1195 sizeof (pc_register_id
), &pc_register_id
);
1196 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1198 warning (_("Failed to get PC register from amd-dbgapi"));
1202 set_gdbarch_pc_regnum (gdbarch
, tdep
->regnum_map
[pc_register_id
]);
1203 set_gdbarch_ps_regnum (gdbarch
, -1);
1204 set_gdbarch_sp_regnum (gdbarch
, -1);
1205 set_gdbarch_fp0_regnum (gdbarch
, -1);
1207 set_gdbarch_dwarf2_reg_to_regnum (gdbarch
, amdgpu_dwarf_reg_to_regnum
);
1209 set_gdbarch_return_value_as_value (gdbarch
, amdgpu_return_value_as_value
);
1211 /* Register representation. */
1212 set_gdbarch_register_name (gdbarch
, amdgpu_register_name
);
1213 set_gdbarch_register_type (gdbarch
, amdgpu_register_type
);
1214 set_gdbarch_register_reggroup_p (gdbarch
, amdgpu_register_reggroup_p
);
1217 set_gdbarch_print_insn (gdbarch
, print_insn_amdgpu
);
1220 amd_dbgapi_size_t max_insn_length
= 0;
1221 status
= amd_dbgapi_architecture_get_info
1222 (architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_LARGEST_INSTRUCTION_SIZE
,
1223 sizeof (max_insn_length
), &max_insn_length
);
1224 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1225 error (_("amd_dbgapi_architecture_get_info failed"));
1227 set_gdbarch_max_insn_length (gdbarch
, max_insn_length
);
1229 status
= amd_dbgapi_architecture_get_info
1230 (architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_SIZE
,
1231 sizeof (tdep
->breakpoint_instruction_size
),
1232 &tdep
->breakpoint_instruction_size
);
1233 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1234 error (_("amd_dbgapi_architecture_get_info failed"));
1236 gdb_byte
*breakpoint_instruction_bytes
;
1237 status
= amd_dbgapi_architecture_get_info
1238 (architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION
,
1239 sizeof (breakpoint_instruction_bytes
), &breakpoint_instruction_bytes
);
1240 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1241 error (_("amd_dbgapi_architecture_get_info failed"));
1243 tdep
->breakpoint_instruction_bytes
.reset (breakpoint_instruction_bytes
);
1245 set_gdbarch_breakpoint_kind_from_pc (gdbarch
,
1246 amdgpu_breakpoint_kind_from_pc
);
1247 set_gdbarch_sw_breakpoint_from_kind (gdbarch
,
1248 amdgpu_sw_breakpoint_from_kind
);
1250 amd_dbgapi_size_t pc_adjust
;
1251 status
= amd_dbgapi_architecture_get_info
1253 AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_PC_ADJUST
,
1254 sizeof (pc_adjust
), &pc_adjust
);
1255 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1256 error (_("amd_dbgapi_architecture_get_info failed"));
1258 set_gdbarch_decr_pc_after_break (gdbarch
, pc_adjust
);
1260 return gdbarch_u
.release ();
1263 #if defined GDB_SELF_TEST
1266 amdgpu_register_type_parse_test ()
1269 /* A type that exercises flags and enums, in particular looking up an
1270 existing enum type by name. */
1271 const char *flags_type_str
=
1278 } FP_ROUND.32 @0-1; \
1279 enum fp_round FP_ROUND.64_16 @2-3; \
1281 FLUSH_SRC_DST = 0, \
1285 } FP_DENORM.32 @4-5; \
1286 enum fp_denorm FP_DENORM.64_16 @6-7; \
1287 bool DX10_CLAMP @8; \
1289 bool LOD_CLAMPED @10; \
1290 bool DEBUG_EN @11; \
1291 bool EXCP_EN.INVALID @12; \
1292 bool EXCP_EN.DENORM @13; \
1293 bool EXCP_EN.DIV0 @14; \
1294 bool EXCP_EN.OVERFLOW @15; \
1295 bool EXCP_EN.UNDERFLOW @16; \
1296 bool EXCP_EN.INEXACT @17; \
1297 bool EXCP_EN.INT_DIV0 @18; \
1298 bool EXCP_EN.ADDR_WATCH @19; \
1299 bool FP16_OVFL @23; \
1300 bool POPS_PACKER0 @24; \
1301 bool POPS_PACKER1 @25; \
1302 bool DISABLE_PERF @26; \
1303 bool GPR_IDX_EN @27; \
1305 uint32_t CSP @29-31; \
1307 amd_dbgapi_register_type_map type_map
;
1308 const amd_dbgapi_register_type
&type
1309 = parse_amd_dbgapi_register_type (flags_type_str
, type_map
);
1311 gdb_assert (type
.kind () == amd_dbgapi_register_type::kind::FLAGS
);
1314 = gdb::checked_static_cast
<const amd_dbgapi_register_type_flags
&> (type
);
1315 gdb_assert (f
.size () == 23);
1317 /* Check the two "FP_ROUND" fields. */
1318 auto check_fp_round_field
1319 = [] (const char *name
, const amd_dbgapi_register_type_flags::field
&field
)
1321 gdb_assert (field
.name
== name
);
1322 gdb_assert (field
.type
->kind ()
1323 == amd_dbgapi_register_type::kind::ENUM
);
1326 = gdb::checked_static_cast
<const amd_dbgapi_register_type_enum
&>
1328 gdb_assert (e
.size () == 4);
1329 gdb_assert (e
[0].name
== "NEAREST_EVEN");
1330 gdb_assert (e
[0].value
== 0);
1331 gdb_assert (e
[3].name
== "ZERO");
1332 gdb_assert (e
[3].value
== 3);
1335 check_fp_round_field ("FP_ROUND.32", f
[0]);
1336 check_fp_round_field ("FP_ROUND.64_16", f
[1]);
1338 /* Check the "CSP" field. */
1339 gdb_assert (f
[22].name
== "CSP");
1340 gdb_assert (f
[22].type
->kind () == amd_dbgapi_register_type::kind::INTEGER
);
1343 = gdb::checked_static_cast
<const amd_dbgapi_register_type_integer
&>
1345 gdb_assert (i
.bit_size () == 32);
1346 gdb_assert (i
.is_unsigned ());
1350 /* Test the vector type. */
1351 const char *vector_type_str
= "int32_t[64]";
1352 amd_dbgapi_register_type_map type_map
;
1353 const amd_dbgapi_register_type
&type
1354 = parse_amd_dbgapi_register_type (vector_type_str
, type_map
);
1356 gdb_assert (type
.kind () == amd_dbgapi_register_type::kind::VECTOR
);
1359 = gdb::checked_static_cast
<const amd_dbgapi_register_type_vector
&>
1361 gdb_assert (v
.count () == 64);
1363 const auto &et
= v
.element_type ();
1364 gdb_assert (et
.kind () == amd_dbgapi_register_type::kind::INTEGER
);
1367 = gdb::checked_static_cast
<const amd_dbgapi_register_type_integer
&> (et
);
1368 gdb_assert (i
.bit_size () == 32);
1369 gdb_assert (!i
.is_unsigned ());
1375 void _initialize_amdgpu_tdep ();
1378 _initialize_amdgpu_tdep ()
1380 gdbarch_register (bfd_arch_amdgcn
, amdgpu_gdbarch_init
, NULL
,
1381 amdgpu_supports_arch_info
);
1382 #if defined GDB_SELF_TEST
1383 selftests::register_test ("amdgpu-register-type-parse-flags-fields",
1384 amdgpu_register_type_parse_test
);