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 "reggroups.h"
34 /* See amdgpu-tdep.h. */
37 is_amdgpu_arch (struct gdbarch
*arch
)
39 gdb_assert (arch
!= nullptr);
40 return gdbarch_bfd_arch_info (arch
)->arch
== bfd_arch_amdgcn
;
43 /* See amdgpu-tdep.h. */
46 get_amdgpu_gdbarch_tdep (gdbarch
*arch
)
48 return gdbarch_tdep
<amdgpu_gdbarch_tdep
> (arch
);
51 /* Dummy implementation of gdbarch_return_value_as_value. */
53 static return_value_convention
54 amdgpu_return_value_as_value (gdbarch
*arch
, value
*function
, type
*valtype
,
55 regcache
*regcache
, value
**read_value
,
56 const gdb_byte
*writebuf
)
58 gdb_assert_not_reached ("not implemented");
61 /* Return the name of register REGNUM. */
64 amdgpu_register_name (struct gdbarch
*gdbarch
, int regnum
)
66 /* The list of registers reported by amd-dbgapi for a given architecture
67 contains some duplicate names. For instance, there is an "exec" register
68 for waves in the wave32 mode and one for the waves in the wave64 mode.
69 However, at most one register with a given name is actually allocated for
70 a specific wave. If INFERIOR_PTID represents a GPU wave, we query
71 amd-dbgapi to know whether the requested register actually exists for the
72 current wave, so there won't be duplicates in the the register names we
75 But there are two known cases where INFERIOR_PTID doesn't represent a GPU
78 - The user does "set arch amdgcn:gfxNNN" followed with "maint print
80 - The "register_name" selftest
82 In these cases, we can't query amd-dbgapi to know whether we should hide
83 the register or not. The "register_name" selftest checks that there aren't
84 duplicates in the register names returned by the gdbarch, so if we simply
85 return all register names, that test will fail. The other simple option is
86 to never return a register name, which is what we do here. */
87 if (!ptid_is_gpu (inferior_ptid
))
90 amd_dbgapi_wave_id_t wave_id
= get_amd_dbgapi_wave_id (inferior_ptid
);
91 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
93 amd_dbgapi_register_exists_t register_exists
;
94 if (amd_dbgapi_wave_register_exists (wave_id
, tdep
->register_ids
[regnum
],
96 != AMD_DBGAPI_STATUS_SUCCESS
97 || register_exists
!= AMD_DBGAPI_REGISTER_PRESENT
)
100 return tdep
->register_names
[regnum
].c_str ();
103 /* Return the internal register number for the DWARF register number DWARF_REG.
105 Return -1 if there's no internal register mapping to DWARF_REG. */
108 amdgpu_dwarf_reg_to_regnum (struct gdbarch
*gdbarch
, int dwarf_reg
)
110 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
112 if (dwarf_reg
< tdep
->dwarf_regnum_to_gdb_regnum
.size ())
113 return tdep
->dwarf_regnum_to_gdb_regnum
[dwarf_reg
];
118 /* A hierarchy of classes to represent an amd-dbgapi register type. */
120 struct amd_dbgapi_register_type
133 amd_dbgapi_register_type (kind kind
, std::string lookup_name
)
134 : m_kind (kind
), m_lookup_name (std::move (lookup_name
))
137 virtual ~amd_dbgapi_register_type () = default;
139 /* Return the type's kind. */
143 /* Name to use for this type in the existing type map. */
144 const std::string
&lookup_name () const
145 { return m_lookup_name
; }
149 std::string m_lookup_name
;
152 using amd_dbgapi_register_type_up
= std::unique_ptr
<amd_dbgapi_register_type
>;
154 struct amd_dbgapi_register_type_integer
: public amd_dbgapi_register_type
156 amd_dbgapi_register_type_integer (bool is_unsigned
, unsigned int bit_size
)
157 : amd_dbgapi_register_type
159 string_printf ("%sint%d", is_unsigned
? "u" : "", bit_size
)),
160 m_is_unsigned (is_unsigned
),
161 m_bit_size (bit_size
)
164 bool is_unsigned () const
165 { return m_is_unsigned
; }
167 unsigned int bit_size () const
168 { return m_bit_size
; }
172 unsigned int m_bit_size
;
175 struct amd_dbgapi_register_type_float
: public amd_dbgapi_register_type
177 amd_dbgapi_register_type_float ()
178 : amd_dbgapi_register_type (kind::FLOAT
, "float")
182 struct amd_dbgapi_register_type_double
: public amd_dbgapi_register_type
184 amd_dbgapi_register_type_double ()
185 : amd_dbgapi_register_type (kind::DOUBLE
, "double")
189 struct amd_dbgapi_register_type_vector
: public amd_dbgapi_register_type
191 amd_dbgapi_register_type_vector (const amd_dbgapi_register_type
&element_type
,
193 : amd_dbgapi_register_type (kind::VECTOR
,
194 make_lookup_name (element_type
, count
)),
195 m_element_type (element_type
),
199 const amd_dbgapi_register_type
&element_type () const
200 { return m_element_type
; }
202 unsigned int count () const
205 static std::string make_lookup_name
206 (const amd_dbgapi_register_type
&element_type
, unsigned int count
)
208 return string_printf ("%s[%d]", element_type
.lookup_name ().c_str (),
213 const amd_dbgapi_register_type
&m_element_type
;
214 unsigned int m_count
;
217 struct amd_dbgapi_register_type_code_ptr
: public amd_dbgapi_register_type
219 amd_dbgapi_register_type_code_ptr ()
220 : amd_dbgapi_register_type (kind::CODE_PTR
, "void (*)()")
224 struct amd_dbgapi_register_type_flags
: public amd_dbgapi_register_type
229 unsigned int bit_pos_start
;
230 unsigned int bit_pos_end
;
231 const amd_dbgapi_register_type
*type
;
234 using container_type
= std::vector
<field
>;
235 using const_iterator_type
= container_type::const_iterator
;
237 amd_dbgapi_register_type_flags (unsigned int bit_size
, std::string_view name
)
238 : amd_dbgapi_register_type (kind::FLAGS
,
239 make_lookup_name (bit_size
, name
)),
240 m_bit_size (bit_size
),
241 m_name (std::move (name
))
244 unsigned int bit_size () const
245 { return m_bit_size
; }
247 void add_field (std::string name
, unsigned int bit_pos_start
,
248 unsigned int bit_pos_end
,
249 const amd_dbgapi_register_type
*type
)
251 m_fields
.push_back (field
{std::move (name
), bit_pos_start
,
255 container_type::size_type
size () const
256 { return m_fields
.size (); }
258 const field
&operator[] (container_type::size_type pos
) const
259 { return m_fields
[pos
]; }
261 const_iterator_type
begin () const
262 { return m_fields
.begin (); }
264 const_iterator_type
end () const
265 { return m_fields
.end (); }
267 const std::string
&name () const
270 static std::string
make_lookup_name (int bits
, std::string_view name
)
272 std::string res
= string_printf ("flags%d_t ", bits
);
273 res
.append (name
.data (), name
.size ());
278 unsigned int m_bit_size
;
279 container_type m_fields
;
283 using amd_dbgapi_register_type_flags_up
284 = std::unique_ptr
<amd_dbgapi_register_type_flags
>;
286 struct amd_dbgapi_register_type_enum
: public amd_dbgapi_register_type
294 using container_type
= std::vector
<enumerator
>;
295 using const_iterator_type
= container_type::const_iterator
;
297 amd_dbgapi_register_type_enum (std::string_view name
)
298 : amd_dbgapi_register_type (kind::ENUM
, make_lookup_name (name
)),
299 m_name (name
.data (), name
.length ())
302 void set_bit_size (int bit_size
)
303 { m_bit_size
= bit_size
; }
305 unsigned int bit_size () const
306 { return m_bit_size
; }
308 void add_enumerator (std::string name
, ULONGEST value
)
309 { m_enumerators
.push_back (enumerator
{std::move (name
), value
}); }
311 container_type::size_type
size () const
312 { return m_enumerators
.size (); }
314 const enumerator
&operator[] (container_type::size_type pos
) const
315 { return m_enumerators
[pos
]; }
317 const_iterator_type
begin () const
318 { return m_enumerators
.begin (); }
320 const_iterator_type
end () const
321 { return m_enumerators
.end (); }
323 const std::string
&name () const
326 static std::string
make_lookup_name (std::string_view name
)
328 std::string res
= "enum ";
329 res
.append (name
.data (), name
.length ());
334 unsigned int m_bit_size
= 32;
335 container_type m_enumerators
;
339 using amd_dbgapi_register_type_enum_up
340 = std::unique_ptr
<amd_dbgapi_register_type_enum
>;
342 /* Map type lookup names to types. */
343 using amd_dbgapi_register_type_map
344 = std::unordered_map
<std::string
, amd_dbgapi_register_type_up
>;
346 /* Parse S as a ULONGEST, raise an error on overflow. */
349 try_strtoulst (std::string_view s
)
352 ULONGEST value
= strtoulst (s
.data (), nullptr, 0);
354 error (_("Failed to parse integer."));
359 /* Shared regex bits. */
360 #define IDENTIFIER "[A-Za-z0-9_.]+"
362 #define WSOPT "[ \t]*"
364 static const amd_dbgapi_register_type
&
365 parse_amd_dbgapi_register_type (std::string_view type_name
,
366 amd_dbgapi_register_type_map
&type_map
);
369 /* parse_amd_dbgapi_register_type helper for enum types. */
372 parse_amd_dbgapi_register_type_enum_fields
373 (amd_dbgapi_register_type_enum
&enum_type
, std::string_view fields
)
375 compiled_regex
regex (/* name */
380 WSOPT
"(," WSOPT
")?",
382 _("Error in AMDGPU enum register type regex"));
383 regmatch_t matches
[4];
385 while (!fields
.empty ())
387 int res
= regex
.exec (fields
.data (), ARRAY_SIZE (matches
), matches
, 0);
388 if (res
== REG_NOMATCH
)
389 error (_("Failed to parse enum fields"));
391 auto sv_from_match
= [fields
] (const regmatch_t
&m
)
392 { return fields
.substr (m
.rm_so
, m
.rm_eo
- m
.rm_so
); };
394 std::string_view name
= sv_from_match (matches
[1]);
395 std::string_view value_str
= sv_from_match (matches
[2]);
396 ULONGEST value
= try_strtoulst (value_str
);
398 if (value
> std::numeric_limits
<uint32_t>::max ())
399 enum_type
.set_bit_size (64);
401 enum_type
.add_enumerator (std::string (name
), value
);
403 fields
= fields
.substr (matches
[0].rm_eo
);
407 /* parse_amd_dbgapi_register_type helper for flags types. */
410 parse_amd_dbgapi_register_type_flags_fields
411 (amd_dbgapi_register_type_flags
&flags_type
,
412 int bits
, std::string_view name
, std::string_view fields
,
413 amd_dbgapi_register_type_map
&type_map
)
415 gdb_assert (bits
== 32 || bits
== 64);
417 std::string regex_str
418 = string_printf (/* type */
419 "^(bool|uint%d_t|enum" WS IDENTIFIER WSOPT
"(\\{[^}]*})?)"
422 "(" IDENTIFIER
")" WSOPT
424 "@([0-9]+)(-[0-9]+)?" WSOPT
";" WSOPT
,
426 compiled_regex
regex (regex_str
.c_str (), REG_EXTENDED
,
427 _("Error in AMDGPU register type flags fields regex"));
428 regmatch_t matches
[6];
430 while (!fields
.empty ())
432 int res
= regex
.exec (fields
.data (), ARRAY_SIZE (matches
), matches
, 0);
433 if (res
== REG_NOMATCH
)
434 error (_("Failed to parse flags type fields string"));
436 auto sv_from_match
= [fields
] (const regmatch_t
&m
)
437 { return fields
.substr (m
.rm_so
, m
.rm_eo
- m
.rm_so
); };
439 std::string_view field_type_str
= sv_from_match (matches
[1]);
440 std::string_view field_name
= sv_from_match (matches
[3]);
441 std::string_view pos_begin_str
= sv_from_match (matches
[4]);
442 ULONGEST pos_begin
= try_strtoulst (pos_begin_str
);
444 if (field_type_str
== "bool")
445 flags_type
.add_field (std::string (field_name
), pos_begin
, pos_begin
,
449 if (matches
[5].rm_so
== -1)
450 error (_("Missing end bit position"));
452 std::string_view pos_end_str
= sv_from_match (matches
[5]);
453 ULONGEST pos_end
= try_strtoulst (pos_end_str
.substr (1));
454 const amd_dbgapi_register_type
&field_type
455 = parse_amd_dbgapi_register_type (field_type_str
, type_map
);
456 flags_type
.add_field (std::string (field_name
), pos_begin
, pos_end
,
460 fields
= fields
.substr (matches
[0].rm_eo
);
464 /* parse_amd_dbgapi_register_type helper for scalars. */
466 static const amd_dbgapi_register_type
&
467 parse_amd_dbgapi_register_type_scalar (std::string_view name
,
468 amd_dbgapi_register_type_map
&type_map
)
470 std::string
name_str (name
);
471 auto it
= type_map
.find (name_str
);
472 if (it
!= type_map
.end ())
474 enum amd_dbgapi_register_type::kind kind
= it
->second
->kind ();
475 if (kind
!= amd_dbgapi_register_type::kind::INTEGER
476 && kind
!= amd_dbgapi_register_type::kind::FLOAT
477 && kind
!= amd_dbgapi_register_type::kind::DOUBLE
478 && kind
!= amd_dbgapi_register_type::kind::CODE_PTR
)
479 error (_("type mismatch"));
484 amd_dbgapi_register_type_up type
;
485 if (name
== "int32_t")
486 type
.reset (new amd_dbgapi_register_type_integer (false, 32));
487 else if (name
== "uint32_t")
488 type
.reset (new amd_dbgapi_register_type_integer (true, 32));
489 else if (name
== "int64_t")
490 type
.reset (new amd_dbgapi_register_type_integer (false, 64));
491 else if (name
== "uint64_t")
492 type
.reset (new amd_dbgapi_register_type_integer (true, 64));
493 else if (name
== "float")
494 type
.reset (new amd_dbgapi_register_type_float ());
495 else if (name
== "double")
496 type
.reset (new amd_dbgapi_register_type_double ());
497 else if (name
== "void (*)()")
498 type
.reset (new amd_dbgapi_register_type_code_ptr ());
500 error (_("unknown type %s"), name_str
.c_str ());
502 auto insertion_pair
= type_map
.emplace (name
, std::move (type
));
503 return *insertion_pair
.first
->second
;
506 /* Parse an amd-dbgapi register type string into an amd_dbgapi_register_type
509 See the documentation of AMD_DBGAPI_REGISTER_INFO_TYPE in amd-dbgapi.h for
510 details about the format. */
512 static const amd_dbgapi_register_type
&
513 parse_amd_dbgapi_register_type (std::string_view type_str
,
514 amd_dbgapi_register_type_map
&type_map
)
516 size_t pos_open_bracket
= type_str
.find_last_of ('[');
517 auto sv_from_match
= [type_str
] (const regmatch_t
&m
)
518 { return type_str
.substr (m
.rm_so
, m
.rm_eo
- m
.rm_so
); };
520 if (pos_open_bracket
!= std::string_view::npos
)
523 std::string_view element_type_str
524 = type_str
.substr (0, pos_open_bracket
);
525 const amd_dbgapi_register_type
&element_type
526 = parse_amd_dbgapi_register_type (element_type_str
, type_map
);
528 size_t pos_close_bracket
= type_str
.find_last_of (']');
529 gdb_assert (pos_close_bracket
!= std::string_view::npos
);
530 std::string_view count_str_view
531 = type_str
.substr (pos_open_bracket
+ 1,
532 pos_close_bracket
- pos_open_bracket
);
533 std::string
count_str (count_str_view
);
534 unsigned int count
= std::stoul (count_str
);
536 std::string lookup_name
537 = amd_dbgapi_register_type_vector::make_lookup_name (element_type
, count
);
538 auto existing_type_it
= type_map
.find (lookup_name
);
539 if (existing_type_it
!= type_map
.end ())
541 gdb_assert (existing_type_it
->second
->kind ()
542 == amd_dbgapi_register_type::kind::VECTOR
);
543 return *existing_type_it
->second
;
546 amd_dbgapi_register_type_up type
547 (new amd_dbgapi_register_type_vector (element_type
, count
));
549 = type_map
.emplace (type
->lookup_name (), std::move (type
));
550 return *insertion_pair
.first
->second
;
553 if (type_str
.find ("flags32_t") == 0 || type_str
.find ("flags64_t") == 0)
555 /* Split 'type_str' into 4 tokens: "(type) (name) ({ (fields) })". */
556 compiled_regex
regex ("^(flags32_t|flags64_t)"
557 WS
"(" IDENTIFIER
")" WSOPT
558 "(\\{" WSOPT
"(.*)})?",
560 _("Error in AMDGPU register type regex"));
562 regmatch_t matches
[5];
563 int res
= regex
.exec (type_str
.data (), ARRAY_SIZE (matches
), matches
, 0);
564 if (res
== REG_NOMATCH
)
565 error (_("Failed to parse flags type string"));
567 std::string_view flags_keyword
= sv_from_match (matches
[1]);
568 unsigned int bit_size
= flags_keyword
== "flags32_t" ? 32 : 64;
569 std::string_view name
= sv_from_match (matches
[2]);
570 std::string lookup_name
571 = amd_dbgapi_register_type_flags::make_lookup_name (bit_size
, name
);
572 auto existing_type_it
= type_map
.find (lookup_name
);
574 if (matches
[3].rm_so
== -1)
576 /* No braces, lookup existing type. */
577 if (existing_type_it
== type_map
.end ())
578 error (_("reference to unknown type %s."),
579 std::string (name
).c_str ());
581 if (existing_type_it
->second
->kind ()
582 != amd_dbgapi_register_type::kind::FLAGS
)
583 error (_("type mismatch"));
585 return *existing_type_it
->second
;
589 /* With braces, it's a definition. */
590 if (existing_type_it
!= type_map
.end ())
591 error (_("re-definition of type %s."),
592 std::string (name
).c_str ());
594 amd_dbgapi_register_type_flags_up flags_type
595 (new amd_dbgapi_register_type_flags (bit_size
, name
));
596 std::string_view fields_without_braces
= sv_from_match (matches
[4]);
598 parse_amd_dbgapi_register_type_flags_fields
599 (*flags_type
, bit_size
, name
, fields_without_braces
, type_map
);
602 = type_map
.emplace (flags_type
->lookup_name (),
603 std::move (flags_type
));
604 return *insertion_pair
.first
->second
;
608 if (type_str
.find ("enum") == 0)
610 compiled_regex
regex ("^enum" WS
"(" IDENTIFIER
")" WSOPT
"(\\{" WSOPT
"([^}]*)})?",
612 _("Error in AMDGPU register type enum regex"));
614 /* Split 'type_name' into 3 tokens: "(name) ( { (fields) } )". */
615 regmatch_t matches
[4];
616 int res
= regex
.exec (type_str
.data (), ARRAY_SIZE (matches
), matches
, 0);
617 if (res
== REG_NOMATCH
)
618 error (_("Failed to parse flags type string"));
620 std::string_view name
= sv_from_match (matches
[1]);
622 std::string lookup_name
623 = amd_dbgapi_register_type_enum::make_lookup_name (name
);
624 auto existing_type_it
= type_map
.find (lookup_name
);
626 if (matches
[2].rm_so
== -1)
628 /* No braces, lookup existing type. */
629 if (existing_type_it
== type_map
.end ())
630 error (_("reference to unknown type %s"),
631 std::string (name
).c_str ());
633 if (existing_type_it
->second
->kind ()
634 != amd_dbgapi_register_type::kind::ENUM
)
635 error (_("type mismatch"));
637 return *existing_type_it
->second
;
641 /* With braces, it's a definition. */
642 if (existing_type_it
!= type_map
.end ())
643 error (_("re-definition of type %s"),
644 std::string (name
).c_str ());
646 amd_dbgapi_register_type_enum_up enum_type
647 (new amd_dbgapi_register_type_enum (name
));
648 std::string_view fields_without_braces
= sv_from_match (matches
[3]);
650 parse_amd_dbgapi_register_type_enum_fields
651 (*enum_type
, fields_without_braces
);
654 = type_map
.emplace (enum_type
->lookup_name (),
655 std::move (enum_type
));
656 return *insertion_pair
.first
->second
;
660 return parse_amd_dbgapi_register_type_scalar (type_str
, type_map
);
663 /* Convert an amd_dbgapi_register_type object to a GDB type. */
666 amd_dbgapi_register_type_to_gdb_type (const amd_dbgapi_register_type
&type
,
667 struct gdbarch
*gdbarch
)
669 switch (type
.kind ())
671 case amd_dbgapi_register_type::kind::INTEGER
:
673 const auto &integer_type
674 = gdb::checked_static_cast
<const amd_dbgapi_register_type_integer
&>
676 switch (integer_type
.bit_size ())
679 if (integer_type
.is_unsigned ())
680 return builtin_type (gdbarch
)->builtin_uint32
;
682 return builtin_type (gdbarch
)->builtin_int32
;
685 if (integer_type
.is_unsigned ())
686 return builtin_type (gdbarch
)->builtin_uint64
;
688 return builtin_type (gdbarch
)->builtin_int64
;
691 gdb_assert_not_reached ("invalid bit size");
695 case amd_dbgapi_register_type::kind::VECTOR
:
697 const auto &vector_type
698 = gdb::checked_static_cast
<const amd_dbgapi_register_type_vector
&>
700 struct type
*element_type
701 = amd_dbgapi_register_type_to_gdb_type (vector_type
.element_type (),
703 return init_vector_type (element_type
, vector_type
.count ());
706 case amd_dbgapi_register_type::kind::FLOAT
:
707 return builtin_type (gdbarch
)->builtin_float
;
709 case amd_dbgapi_register_type::kind::DOUBLE
:
710 return builtin_type (gdbarch
)->builtin_double
;
712 case amd_dbgapi_register_type::kind::CODE_PTR
:
713 return builtin_type (gdbarch
)->builtin_func_ptr
;
715 case amd_dbgapi_register_type::kind::FLAGS
:
717 const auto &flags_type
718 = gdb::checked_static_cast
<const amd_dbgapi_register_type_flags
&>
720 struct type
*gdb_type
721 = arch_flags_type (gdbarch
, flags_type
.name ().c_str (),
722 flags_type
.bit_size ());
724 for (const auto &field
: flags_type
)
726 if (field
.type
== nullptr)
728 gdb_assert (field
.bit_pos_start
== field
.bit_pos_end
);
729 append_flags_type_flag (gdb_type
, field
.bit_pos_start
,
730 field
.name
.c_str ());
734 struct type
*field_type
735 = amd_dbgapi_register_type_to_gdb_type (*field
.type
, gdbarch
);
736 gdb_assert (field_type
!= nullptr);
737 append_flags_type_field
738 (gdb_type
, field
.bit_pos_start
,
739 field
.bit_pos_end
- field
.bit_pos_start
+ 1,
740 field_type
, field
.name
.c_str ());
747 case amd_dbgapi_register_type::kind::ENUM
:
749 const auto &enum_type
750 = gdb::checked_static_cast
<const amd_dbgapi_register_type_enum
&>
752 struct type
*gdb_type
753 = (type_allocator (gdbarch
)
754 .new_type (TYPE_CODE_ENUM
, enum_type
.bit_size (),
755 enum_type
.name ().c_str ()));
757 gdb_type
->alloc_fields (enum_type
.size ());
758 gdb_type
->set_is_unsigned (true);
760 for (size_t i
= 0; i
< enum_type
.size (); ++i
)
762 const auto &field
= enum_type
[i
];
763 gdb_type
->field (i
).set_name (xstrdup (field
.name
.c_str ()));
764 gdb_type
->field (i
).set_loc_enumval (field
.value
);
771 gdb_assert_not_reached ("unhandled amd_dbgapi_register_type kind");
776 amdgpu_register_type (struct gdbarch
*gdbarch
, int regnum
)
778 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
780 if (tdep
->register_types
[regnum
] == nullptr)
782 /* This is done lazily (not at gdbarch initialization time), because it
783 requires access to builtin_type, which can't be used while the gdbarch
784 is not fully initialized. */
786 amd_dbgapi_status_t status
787 = amd_dbgapi_register_get_info (tdep
->register_ids
[regnum
],
788 AMD_DBGAPI_REGISTER_INFO_TYPE
,
789 sizeof (bytes
), &bytes
);
790 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
791 error (_("Failed to get register type from amd-dbgapi"));
793 gdb::unique_xmalloc_ptr
<char> bytes_holder (bytes
);
794 amd_dbgapi_register_type_map type_map
;
795 const amd_dbgapi_register_type
®ister_type
796 = parse_amd_dbgapi_register_type (bytes
, type_map
);
797 tdep
->register_types
[regnum
]
798 = amd_dbgapi_register_type_to_gdb_type (register_type
, gdbarch
);
799 gdb_assert (tdep
->register_types
[regnum
] != nullptr);
802 return tdep
->register_types
[regnum
];
806 amdgpu_register_reggroup_p (struct gdbarch
*gdbarch
, int regnum
,
807 const reggroup
*group
)
809 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
811 auto it
= tdep
->register_class_map
.find (group
->name ());
812 if (it
== tdep
->register_class_map
.end ())
813 return group
== all_reggroup
;
815 amd_dbgapi_register_class_state_t state
;
816 if (amd_dbgapi_register_is_in_register_class (it
->second
,
817 tdep
->register_ids
[regnum
],
819 != AMD_DBGAPI_STATUS_SUCCESS
)
820 return group
== all_reggroup
;
822 return (state
== AMD_DBGAPI_REGISTER_CLASS_STATE_MEMBER
823 || group
== all_reggroup
);
827 amdgpu_breakpoint_kind_from_pc (struct gdbarch
*gdbarch
, CORE_ADDR
*)
829 return get_amdgpu_gdbarch_tdep (gdbarch
)->breakpoint_instruction_size
;
832 static const gdb_byte
*
833 amdgpu_sw_breakpoint_from_kind (struct gdbarch
*gdbarch
, int kind
, int *size
)
836 return get_amdgpu_gdbarch_tdep (gdbarch
)->breakpoint_instruction_bytes
.get ();
839 struct amdgpu_frame_cache
845 static amdgpu_frame_cache
*
846 amdgpu_frame_cache (const frame_info_ptr
&this_frame
, void **this_cache
)
848 if (*this_cache
!= nullptr)
849 return (struct amdgpu_frame_cache
*) *this_cache
;
851 struct amdgpu_frame_cache
*cache
852 = FRAME_OBSTACK_ZALLOC (struct amdgpu_frame_cache
);
853 (*this_cache
) = cache
;
855 cache
->pc
= get_frame_func (this_frame
);
862 amdgpu_frame_this_id (const frame_info_ptr
&this_frame
, void **this_cache
,
865 struct amdgpu_frame_cache
*cache
866 = amdgpu_frame_cache (this_frame
, this_cache
);
868 if (get_frame_type (this_frame
) == INLINE_FRAME
)
869 (*this_id
) = frame_id_build (cache
->base
, cache
->pc
);
871 (*this_id
) = outer_frame_id
;
873 frame_debug_printf ("this_frame=%d, type=%d, this_id=%s",
874 frame_relative_level (this_frame
),
875 get_frame_type (this_frame
),
876 this_id
->to_string ().c_str ());
880 amdgpu_dummy_id (struct gdbarch
*gdbarch
, const frame_info_ptr
&this_frame
)
882 return frame_id_build (0, get_frame_pc (this_frame
));
885 static struct value
*
886 amdgpu_frame_prev_register (const frame_info_ptr
&this_frame
, void **this_cache
,
889 return frame_unwind_got_register (this_frame
, regnum
, regnum
);
892 static const frame_unwind amdgpu_frame_unwind
= {
895 default_frame_unwind_stop_reason
,
896 amdgpu_frame_this_id
,
897 amdgpu_frame_prev_register
,
899 default_frame_sniffer
,
905 print_insn_amdgpu (bfd_vma memaddr
, struct disassemble_info
*info
)
907 gdb_disassemble_info
*di
908 = static_cast<gdb_disassemble_info
*> (info
->application_data
);
910 /* Try to read at most INSTRUCTION_SIZE bytes. */
912 amd_dbgapi_size_t instruction_size
= gdbarch_max_insn_length (di
->arch ());
913 gdb::byte_vector
buffer (instruction_size
);
915 /* read_memory_func doesn't support partial reads, so if the read
916 fails, try one byte less, on and on until we manage to read
917 something. A case where this would happen is if we're trying to
918 read the last instruction at the end of a file section and that
919 instruction is smaller than the largest instruction. */
920 while (instruction_size
> 0)
922 int ret
= info
->read_memory_func (memaddr
, buffer
.data (),
923 instruction_size
, info
);
930 if (instruction_size
== 0)
932 info
->memory_error_func (-1, memaddr
, info
);
936 amd_dbgapi_architecture_id_t architecture_id
;
937 amd_dbgapi_status_t status
938 = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (di
->arch ())->mach
,
940 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
943 auto symbolizer
= [] (amd_dbgapi_symbolizer_id_t symbolizer_id
,
944 amd_dbgapi_global_address_t address
,
945 char **symbol_text
) -> amd_dbgapi_status_t
947 gdb_disassemble_info
*disasm_info
948 = reinterpret_cast<gdb_disassemble_info
*> (symbolizer_id
);
949 gdb_printing_disassembler
*disasm
950 = dynamic_cast<gdb_printing_disassembler
*> (disasm_info
);
951 gdb_assert (disasm
!= nullptr);
953 string_file
string (disasm
->stream ()->can_emit_style_escape ());
954 print_address (disasm
->arch (), address
, &string
);
955 *symbol_text
= xstrdup (string
.c_str ());
957 return AMD_DBGAPI_STATUS_SUCCESS
;
959 auto symbolizer_id
= reinterpret_cast<amd_dbgapi_symbolizer_id_t
> (di
);
960 char *instruction_text
= nullptr;
961 status
= amd_dbgapi_disassemble_instruction (architecture_id
, memaddr
,
967 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
970 status
= amd_dbgapi_architecture_get_info
972 AMD_DBGAPI_ARCHITECTURE_INFO_MINIMUM_INSTRUCTION_ALIGNMENT
,
973 sizeof (alignment
), &alignment
);
974 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
975 error (_("amd_dbgapi_architecture_get_info failed"));
977 info
->fprintf_func (di
, "<illegal instruction>");
979 /* Skip to the next valid instruction address. */
980 return align_up (memaddr
+ 1, alignment
) - memaddr
;
983 /* Print the instruction. */
984 info
->fprintf_func (di
, "%s", instruction_text
);
986 /* Free the memory allocated by the amd-dbgapi. */
987 xfree (instruction_text
);
989 return static_cast<int> (instruction_size
);
993 amdgpu_skip_prologue (struct gdbarch
*gdbarch
, CORE_ADDR start_pc
)
997 /* See if we can determine the end of the prologue via the symbol table.
998 If so, then return either PC, or the PC after the prologue, whichever
1000 if (find_pc_partial_function (start_pc
, nullptr, &func_addr
, nullptr))
1002 CORE_ADDR post_prologue_pc
1003 = skip_prologue_using_sal (gdbarch
, func_addr
);
1004 struct compunit_symtab
*cust
= find_pc_compunit_symtab (func_addr
);
1006 /* Clang always emits a line note before the prologue and another
1007 one after. We trust clang to emit usable line notes. */
1008 if (post_prologue_pc
!= 0
1010 && cust
->producer () != nullptr
1011 && producer_is_llvm (cust
->producer ()))
1012 return std::max (start_pc
, post_prologue_pc
);
1019 amdgpu_supports_arch_info (const struct bfd_arch_info
*info
)
1021 amd_dbgapi_architecture_id_t architecture_id
;
1022 amd_dbgapi_status_t status
1023 = amd_dbgapi_get_architecture (info
->mach
, &architecture_id
);
1025 gdb_assert (status
!= AMD_DBGAPI_STATUS_ERROR_NOT_INITIALIZED
);
1026 return status
== AMD_DBGAPI_STATUS_SUCCESS
;
1029 static struct gdbarch
*
1030 amdgpu_gdbarch_init (struct gdbarch_info info
, struct gdbarch_list
*arches
)
1032 /* If there is already a candidate, use it. */
1033 arches
= gdbarch_list_lookup_by_info (arches
, &info
);
1034 if (arches
!= nullptr)
1035 return arches
->gdbarch
;
1037 /* Allocate space for the new architecture. */
1038 gdbarch_up gdbarch_u
1039 (gdbarch_alloc (&info
, gdbarch_tdep_up (new amdgpu_gdbarch_tdep
)));
1040 gdbarch
*gdbarch
= gdbarch_u
.get ();
1041 amdgpu_gdbarch_tdep
*tdep
= gdbarch_tdep
<amdgpu_gdbarch_tdep
> (gdbarch
);
1044 set_gdbarch_char_signed (gdbarch
, 0);
1045 set_gdbarch_ptr_bit (gdbarch
, 64);
1046 set_gdbarch_addr_bit (gdbarch
, 64);
1047 set_gdbarch_short_bit (gdbarch
, 16);
1048 set_gdbarch_int_bit (gdbarch
, 32);
1049 set_gdbarch_long_bit (gdbarch
, 64);
1050 set_gdbarch_long_long_bit (gdbarch
, 64);
1051 set_gdbarch_float_bit (gdbarch
, 32);
1052 set_gdbarch_double_bit (gdbarch
, 64);
1053 set_gdbarch_long_double_bit (gdbarch
, 128);
1054 set_gdbarch_half_format (gdbarch
, floatformats_ieee_half
);
1055 set_gdbarch_float_format (gdbarch
, floatformats_ieee_single
);
1056 set_gdbarch_double_format (gdbarch
, floatformats_ieee_double
);
1057 set_gdbarch_long_double_format (gdbarch
, floatformats_ieee_double
);
1059 /* Frame interpretation. */
1060 set_gdbarch_skip_prologue (gdbarch
, amdgpu_skip_prologue
);
1061 set_gdbarch_inner_than (gdbarch
, core_addr_greaterthan
);
1062 dwarf2_append_unwinders (gdbarch
);
1063 frame_unwind_append_unwinder (gdbarch
, &amdgpu_frame_unwind
);
1064 set_gdbarch_dummy_id (gdbarch
, amdgpu_dummy_id
);
1066 /* Registers and memory. */
1067 amd_dbgapi_architecture_id_t architecture_id
;
1068 amd_dbgapi_status_t status
1069 = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch
)->mach
,
1071 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1073 warning (_("Failed to get architecture from amd-dbgapi"));
1078 /* Add register groups. */
1079 size_t register_class_count
;
1080 amd_dbgapi_register_class_id_t
*register_class_ids
;
1081 status
= amd_dbgapi_architecture_register_class_list (architecture_id
,
1082 ®ister_class_count
,
1083 ®ister_class_ids
);
1084 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1086 warning (_("Failed to get register class list from amd-dbgapi"));
1090 gdb::unique_xmalloc_ptr
<amd_dbgapi_register_class_id_t
>
1091 register_class_ids_holder (register_class_ids
);
1093 for (size_t i
= 0; i
< register_class_count
; ++i
)
1096 status
= amd_dbgapi_architecture_register_class_get_info
1097 (register_class_ids
[i
], AMD_DBGAPI_REGISTER_CLASS_INFO_NAME
,
1098 sizeof (bytes
), &bytes
);
1099 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1101 warning (_("Failed to get register class name from amd-dbgapi"));
1105 gdb::unique_xmalloc_ptr
<char> name (bytes
);
1107 auto inserted
= tdep
->register_class_map
.emplace (name
.get (),
1108 register_class_ids
[i
]);
1109 gdb_assert (inserted
.second
);
1111 /* Avoid creating a user reggroup with the same name as some built-in
1112 reggroup, such as "general", "system", "vector", etc. */
1113 if (reggroup_find (gdbarch
, name
.get ()) != nullptr)
1116 /* Allocate the reggroup in the gdbarch. */
1118 (gdbarch
, reggroup_gdbarch_new (gdbarch
, name
.get (), USER_REGGROUP
));
1121 /* Add registers. */
1122 size_t register_count
;
1123 amd_dbgapi_register_id_t
*register_ids
;
1124 status
= amd_dbgapi_architecture_register_list (architecture_id
,
1127 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1129 warning (_("Failed to get register list from amd-dbgapi"));
1133 gdb::unique_xmalloc_ptr
<amd_dbgapi_register_id_t
> register_ids_holder
1136 tdep
->register_ids
.insert (tdep
->register_ids
.end (), ®ister_ids
[0],
1137 ®ister_ids
[register_count
]);
1139 tdep
->register_properties
.resize (register_count
,
1140 AMD_DBGAPI_REGISTER_PROPERTY_NONE
);
1141 for (size_t regnum
= 0; regnum
< register_count
; ++regnum
)
1143 auto ®ister_properties
= tdep
->register_properties
[regnum
];
1144 if (amd_dbgapi_register_get_info (register_ids
[regnum
],
1145 AMD_DBGAPI_REGISTER_INFO_PROPERTIES
,
1146 sizeof (register_properties
),
1147 ®ister_properties
)
1148 != AMD_DBGAPI_STATUS_SUCCESS
)
1150 warning (_("Failed to get register properties from amd-dbgapi"));
1155 set_gdbarch_num_regs (gdbarch
, register_count
);
1156 set_gdbarch_num_pseudo_regs (gdbarch
, 0);
1158 tdep
->register_names
.resize (register_count
);
1159 tdep
->register_types
.resize (register_count
);
1160 for (size_t i
= 0; i
< register_count
; ++i
)
1162 /* Set amd-dbgapi register id -> gdb regnum mapping. */
1163 tdep
->regnum_map
.emplace (tdep
->register_ids
[i
], i
);
1165 /* Get register name. */
1167 status
= amd_dbgapi_register_get_info (tdep
->register_ids
[i
],
1168 AMD_DBGAPI_REGISTER_INFO_NAME
,
1169 sizeof (bytes
), &bytes
);
1170 if (status
== AMD_DBGAPI_STATUS_SUCCESS
)
1172 tdep
->register_names
[i
] = bytes
;
1176 /* Get register DWARF number. */
1178 status
= amd_dbgapi_register_get_info (tdep
->register_ids
[i
],
1179 AMD_DBGAPI_REGISTER_INFO_DWARF
,
1180 sizeof (dwarf_num
), &dwarf_num
);
1181 if (status
== AMD_DBGAPI_STATUS_SUCCESS
)
1183 if (dwarf_num
>= tdep
->dwarf_regnum_to_gdb_regnum
.size ())
1184 tdep
->dwarf_regnum_to_gdb_regnum
.resize (dwarf_num
+ 1, -1);
1186 tdep
->dwarf_regnum_to_gdb_regnum
[dwarf_num
] = i
;
1190 amd_dbgapi_register_id_t pc_register_id
;
1191 status
= amd_dbgapi_architecture_get_info
1192 (architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_PC_REGISTER
,
1193 sizeof (pc_register_id
), &pc_register_id
);
1194 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1196 warning (_("Failed to get PC register from amd-dbgapi"));
1200 set_gdbarch_pc_regnum (gdbarch
, tdep
->regnum_map
[pc_register_id
]);
1201 set_gdbarch_ps_regnum (gdbarch
, -1);
1202 set_gdbarch_sp_regnum (gdbarch
, -1);
1203 set_gdbarch_fp0_regnum (gdbarch
, -1);
1205 set_gdbarch_dwarf2_reg_to_regnum (gdbarch
, amdgpu_dwarf_reg_to_regnum
);
1207 set_gdbarch_return_value_as_value (gdbarch
, amdgpu_return_value_as_value
);
1209 /* Register representation. */
1210 set_gdbarch_register_name (gdbarch
, amdgpu_register_name
);
1211 set_gdbarch_register_type (gdbarch
, amdgpu_register_type
);
1212 set_gdbarch_register_reggroup_p (gdbarch
, amdgpu_register_reggroup_p
);
1215 set_gdbarch_print_insn (gdbarch
, print_insn_amdgpu
);
1218 amd_dbgapi_size_t max_insn_length
= 0;
1219 status
= amd_dbgapi_architecture_get_info
1220 (architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_LARGEST_INSTRUCTION_SIZE
,
1221 sizeof (max_insn_length
), &max_insn_length
);
1222 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1223 error (_("amd_dbgapi_architecture_get_info failed"));
1225 set_gdbarch_max_insn_length (gdbarch
, max_insn_length
);
1227 status
= amd_dbgapi_architecture_get_info
1228 (architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_SIZE
,
1229 sizeof (tdep
->breakpoint_instruction_size
),
1230 &tdep
->breakpoint_instruction_size
);
1231 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1232 error (_("amd_dbgapi_architecture_get_info failed"));
1234 gdb_byte
*breakpoint_instruction_bytes
;
1235 status
= amd_dbgapi_architecture_get_info
1236 (architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION
,
1237 sizeof (breakpoint_instruction_bytes
), &breakpoint_instruction_bytes
);
1238 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1239 error (_("amd_dbgapi_architecture_get_info failed"));
1241 tdep
->breakpoint_instruction_bytes
.reset (breakpoint_instruction_bytes
);
1243 set_gdbarch_breakpoint_kind_from_pc (gdbarch
,
1244 amdgpu_breakpoint_kind_from_pc
);
1245 set_gdbarch_sw_breakpoint_from_kind (gdbarch
,
1246 amdgpu_sw_breakpoint_from_kind
);
1248 amd_dbgapi_size_t pc_adjust
;
1249 status
= amd_dbgapi_architecture_get_info
1251 AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_PC_ADJUST
,
1252 sizeof (pc_adjust
), &pc_adjust
);
1253 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1254 error (_("amd_dbgapi_architecture_get_info failed"));
1256 set_gdbarch_decr_pc_after_break (gdbarch
, pc_adjust
);
1258 return gdbarch_u
.release ();
1261 #if defined GDB_SELF_TEST
1264 amdgpu_register_type_parse_test ()
1267 /* A type that exercises flags and enums, in particular looking up an
1268 existing enum type by name. */
1269 const char *flags_type_str
=
1276 } FP_ROUND.32 @0-1; \
1277 enum fp_round FP_ROUND.64_16 @2-3; \
1279 FLUSH_SRC_DST = 0, \
1283 } FP_DENORM.32 @4-5; \
1284 enum fp_denorm FP_DENORM.64_16 @6-7; \
1285 bool DX10_CLAMP @8; \
1287 bool LOD_CLAMPED @10; \
1288 bool DEBUG_EN @11; \
1289 bool EXCP_EN.INVALID @12; \
1290 bool EXCP_EN.DENORM @13; \
1291 bool EXCP_EN.DIV0 @14; \
1292 bool EXCP_EN.OVERFLOW @15; \
1293 bool EXCP_EN.UNDERFLOW @16; \
1294 bool EXCP_EN.INEXACT @17; \
1295 bool EXCP_EN.INT_DIV0 @18; \
1296 bool EXCP_EN.ADDR_WATCH @19; \
1297 bool FP16_OVFL @23; \
1298 bool POPS_PACKER0 @24; \
1299 bool POPS_PACKER1 @25; \
1300 bool DISABLE_PERF @26; \
1301 bool GPR_IDX_EN @27; \
1303 uint32_t CSP @29-31; \
1305 amd_dbgapi_register_type_map type_map
;
1306 const amd_dbgapi_register_type
&type
1307 = parse_amd_dbgapi_register_type (flags_type_str
, type_map
);
1309 gdb_assert (type
.kind () == amd_dbgapi_register_type::kind::FLAGS
);
1312 = gdb::checked_static_cast
<const amd_dbgapi_register_type_flags
&> (type
);
1313 gdb_assert (f
.size () == 23);
1315 /* Check the two "FP_ROUND" fields. */
1316 auto check_fp_round_field
1317 = [] (const char *name
, const amd_dbgapi_register_type_flags::field
&field
)
1319 gdb_assert (field
.name
== name
);
1320 gdb_assert (field
.type
->kind ()
1321 == amd_dbgapi_register_type::kind::ENUM
);
1324 = gdb::checked_static_cast
<const amd_dbgapi_register_type_enum
&>
1326 gdb_assert (e
.size () == 4);
1327 gdb_assert (e
[0].name
== "NEAREST_EVEN");
1328 gdb_assert (e
[0].value
== 0);
1329 gdb_assert (e
[3].name
== "ZERO");
1330 gdb_assert (e
[3].value
== 3);
1333 check_fp_round_field ("FP_ROUND.32", f
[0]);
1334 check_fp_round_field ("FP_ROUND.64_16", f
[1]);
1336 /* Check the "CSP" field. */
1337 gdb_assert (f
[22].name
== "CSP");
1338 gdb_assert (f
[22].type
->kind () == amd_dbgapi_register_type::kind::INTEGER
);
1341 = gdb::checked_static_cast
<const amd_dbgapi_register_type_integer
&>
1343 gdb_assert (i
.bit_size () == 32);
1344 gdb_assert (i
.is_unsigned ());
1348 /* Test the vector type. */
1349 const char *vector_type_str
= "int32_t[64]";
1350 amd_dbgapi_register_type_map type_map
;
1351 const amd_dbgapi_register_type
&type
1352 = parse_amd_dbgapi_register_type (vector_type_str
, type_map
);
1354 gdb_assert (type
.kind () == amd_dbgapi_register_type::kind::VECTOR
);
1357 = gdb::checked_static_cast
<const amd_dbgapi_register_type_vector
&>
1359 gdb_assert (v
.count () == 64);
1361 const auto &et
= v
.element_type ();
1362 gdb_assert (et
.kind () == amd_dbgapi_register_type::kind::INTEGER
);
1365 = gdb::checked_static_cast
<const amd_dbgapi_register_type_integer
&> (et
);
1366 gdb_assert (i
.bit_size () == 32);
1367 gdb_assert (!i
.is_unsigned ());
1373 void _initialize_amdgpu_tdep ();
1376 _initialize_amdgpu_tdep ()
1378 gdbarch_register (bfd_arch_amdgcn
, amdgpu_gdbarch_init
, NULL
,
1379 amdgpu_supports_arch_info
);
1380 #if defined GDB_SELF_TEST
1381 selftests::register_test ("amdgpu-register-type-parse-flags-fields",
1382 amdgpu_register_type_parse_test
);