1 /* Target-dependent code for the ROCm amdgcn architecture.
3 Copyright (C) 2019-2020 Free Software Foundation, Inc.
4 Copyright (C) 2019-2020 Advanced Micro Devices, Inc. All rights reserved.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include "amdgcn-rocm-tdep.h"
24 #include "arch-utils.h"
25 #include "dwarf2-frame.h"
26 #include "frame-base.h"
27 #include "frame-unwind.h"
31 #include "reggroups.h"
32 #include "rocm-tdep.h"
35 rocm_is_amdgcn_gdbarch (struct gdbarch
*arch
)
37 return (gdbarch_bfd_arch_info (arch
)->arch
== bfd_arch_amdgcn
);
40 /* Return the name of register REGNUM. */
42 amdgcn_register_name (struct gdbarch
*gdbarch
, int regnum
)
44 amd_dbgapi_process_id_t process_id
= get_amd_dbgapi_process_id ();
45 amd_dbgapi_wave_id_t wave_id
= get_amd_dbgapi_wave_id (inferior_ptid
);
46 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
48 amd_dbgapi_size_t unused
;
49 if (amd_dbgapi_wave_register_get_info (
50 process_id
, wave_id
, tdep
->register_ids
[regnum
],
51 AMD_DBGAPI_REGISTER_INFO_SIZE
, sizeof (unused
), &unused
)
52 != AMD_DBGAPI_STATUS_SUCCESS
)
55 return tdep
->register_names
[regnum
].c_str ();
59 amdgcn_dwarf_reg_to_regnum (struct gdbarch
*gdbarch
, int reg
)
61 amd_dbgapi_architecture_id_t architecture_id
;
62 amd_dbgapi_register_id_t register_id
;
64 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch
)->mach
,
66 != AMD_DBGAPI_STATUS_SUCCESS
)
69 if (amd_dbgapi_dwarf_register_to_register (architecture_id
, reg
,
71 != AMD_DBGAPI_STATUS_SUCCESS
)
74 return gdbarch_tdep (gdbarch
)->regnum_map
[register_id
];
78 gdb_type_from_type_name (struct gdbarch
*gdbarch
, const std::string
&type_name
)
83 if ((pos
= type_name
.find_last_of ('[')) != std::string::npos
)
85 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
87 auto it
= tdep
->vector_type_map
.find (type_name
);
88 if (it
!= tdep
->vector_type_map
.end ())
91 struct type
*vector_type
= init_vector_type (
92 gdb_type_from_type_name (gdbarch
, type_name
.substr (0, pos
)),
93 std::stoi (type_name
.substr (pos
+ 1)));
95 tdep
->vector_type_map
[type_name
] = vector_type
;
99 else if (type_name
== "int32_t")
100 return builtin_type (gdbarch
)->builtin_int32
;
101 else if (type_name
== "uint32_t")
102 return builtin_type (gdbarch
)->builtin_uint32
;
103 else if (type_name
== "int64_t")
104 return builtin_type (gdbarch
)->builtin_int64
;
105 else if (type_name
== "uint64_t")
106 return builtin_type (gdbarch
)->builtin_uint64
;
107 else if (type_name
== "float")
108 return builtin_type (gdbarch
)->builtin_float
;
109 else if (type_name
== "double")
110 return builtin_type (gdbarch
)->builtin_double
;
111 else if (type_name
== "void (*)()")
112 return builtin_type (gdbarch
)->builtin_func_ptr
;
114 return builtin_type (gdbarch
)->builtin_void
;
118 amdgcn_register_type (struct gdbarch
*gdbarch
, int regnum
)
120 amd_dbgapi_process_id_t process_id
= get_amd_dbgapi_process_id ();
121 amd_dbgapi_wave_id_t wave_id
= get_amd_dbgapi_wave_id (inferior_ptid
);
122 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
125 if (amd_dbgapi_wave_register_get_info (
126 process_id
, wave_id
, tdep
->register_ids
[regnum
],
127 AMD_DBGAPI_REGISTER_INFO_TYPE
, sizeof (bytes
), &bytes
)
128 == AMD_DBGAPI_STATUS_SUCCESS
)
130 std::string
type_name (bytes
);
133 return gdb_type_from_type_name (gdbarch
, type_name
);
136 return builtin_type (gdbarch
)->builtin_void
;
140 amdgcn_register_reggroup_p (struct gdbarch
*gdbarch
, int regnum
,
141 struct reggroup
*group
)
143 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
144 const char *name
= reggroup_name (group
);
146 auto it
= tdep
->register_class_map
.find (name
);
147 if (it
== tdep
->register_class_map
.end ())
148 return group
== all_reggroup
;
150 amd_dbgapi_architecture_id_t architecture_id
;
152 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch
)->mach
,
154 != AMD_DBGAPI_STATUS_SUCCESS
)
155 return group
== all_reggroup
;
157 amd_dbgapi_register_class_state_t state
;
159 if (amd_dbgapi_register_is_in_register_class (
160 architecture_id
, tdep
->register_ids
[regnum
], it
->second
, &state
)
161 != AMD_DBGAPI_STATUS_SUCCESS
)
162 return group
== all_reggroup
;
164 return state
== AMD_DBGAPI_REGISTER_CLASS_STATE_MEMBER
165 || group
== all_reggroup
;
169 amdgcn_breakpoint_kind_from_pc (struct gdbarch
*gdbarch
, CORE_ADDR
*)
171 return gdbarch_tdep (gdbarch
)->breakpoint_instruction_size
;
174 static const gdb_byte
*
175 amdgcn_sw_breakpoint_from_kind (struct gdbarch
*gdbarch
, int kind
, int *size
)
178 return gdbarch_tdep (gdbarch
)->breakpoint_instruction_bytes
.get ();
181 struct amdgcn_frame_cache
187 static struct amdgcn_frame_cache
*
188 amdgcn_frame_cache (struct frame_info
*this_frame
, void **this_cache
)
191 return (struct amdgcn_frame_cache
*)*this_cache
;
193 struct amdgcn_frame_cache
*cache
194 = FRAME_OBSTACK_ZALLOC (struct amdgcn_frame_cache
);
195 (*this_cache
) = cache
;
197 cache
->pc
= get_frame_func (this_frame
);
204 amdgcn_frame_this_id (struct frame_info
*this_frame
, void **this_cache
,
205 struct frame_id
*this_id
)
207 struct amdgcn_frame_cache
*cache
208 = amdgcn_frame_cache (this_frame
, this_cache
);
210 if (get_frame_type (this_frame
) == INLINE_FRAME
)
211 (*this_id
) = frame_id_build (cache
->base
, cache
->pc
);
213 (*this_id
) = outer_frame_id
;
218 gdb_stdlog
, "{ amdgcn_frame_this_id (this_frame=%d) type=%d -> ",
219 frame_relative_level (this_frame
), get_frame_type (this_frame
));
220 fprint_frame_id (gdb_stdlog
, *this_id
);
221 fprintf_unfiltered (gdb_stdlog
, "}\n");
227 static struct frame_id
228 amdgcn_dummy_id (struct gdbarch
*gdbarch
, struct frame_info
*this_frame
)
230 return frame_id_build (0, get_frame_pc (this_frame
));
233 static struct value
*
234 amdgcn_frame_prev_register (struct frame_info
*this_frame
, void **this_cache
,
237 return frame_unwind_got_register (this_frame
, regnum
, regnum
);
240 static const struct frame_unwind amdgcn_frame_unwind
= {
242 default_frame_unwind_stop_reason
,
243 amdgcn_frame_this_id
,
244 amdgcn_frame_prev_register
,
246 default_frame_sniffer
,
251 struct rocm_displaced_step_closure
: public displaced_step_closure
253 amd_dbgapi_process_id_t process_id
;
254 amd_dbgapi_wave_id_t wave_id
;
255 amd_dbgapi_displaced_stepping_id_t displaced_stepping_id
;
259 amdgcn_rocm_displaced_step_location (struct gdbarch
*gdbarch
)
261 size_t size
= gdbarch_tdep (gdbarch
)->breakpoint_instruction_size
;
262 gdb::unique_xmalloc_ptr
<gdb_byte
> buffer (
263 static_cast<gdb_byte
*> (xmalloc (size
)));
265 /* Read the bytes that were overwritten by the breakpoint instruction. */
266 if (target_read_memory (regcache_read_pc (get_current_regcache ()),
267 buffer
.get (), size
))
270 amd_dbgapi_displaced_stepping_id_t stepping_id
;
271 if (amd_dbgapi_displaced_stepping_start (
272 get_amd_dbgapi_process_id (), get_amd_dbgapi_wave_id (inferior_ptid
),
273 buffer
.get (), &stepping_id
)
274 != AMD_DBGAPI_STATUS_SUCCESS
)
277 return stepping_id
.handle
;
280 static struct displaced_step_closure
*
281 amdgcn_rocm_displaced_step_copy_insn (struct gdbarch
*gdbarch
, CORE_ADDR from
,
282 CORE_ADDR to
, struct regcache
*regcache
)
284 rocm_displaced_step_closure
*closure
= new rocm_displaced_step_closure
;
286 closure
->process_id
= get_amd_dbgapi_process_id ();
287 closure
->wave_id
= get_amd_dbgapi_wave_id (inferior_ptid
);
288 closure
->displaced_stepping_id
= { to
};
294 amdgcn_rocm_displaced_step_fixup (struct gdbarch
*gdbarch
,
295 struct displaced_step_closure
*closure_
,
296 CORE_ADDR from
, CORE_ADDR to
,
297 struct regcache
*regcache
)
299 rocm_displaced_step_closure
*closure
300 = reinterpret_cast<rocm_displaced_step_closure
*> (closure_
);
302 amd_dbgapi_status_t status
= amd_dbgapi_displaced_stepping_complete (
303 closure
->process_id
, closure
->wave_id
, closure
->displaced_stepping_id
);
305 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
306 error (_ ("amd_dbgapi_displaced_stepping_complete failed (rc=%d)"),
309 /* We may have written some registers, so flush the register cache. */
310 registers_changed_ptid (regcache
->ptid ());
314 print_insn_amdgcn (bfd_vma memaddr
, struct disassemble_info
*di
)
316 gdb_disassembler
*self
317 = static_cast<gdb_disassembler
*> (di
->application_data
);
319 /* Try to read at most instruction_size bytes. */
321 amd_dbgapi_size_t instruction_size
= gdbarch_max_insn_length (self
->arch ());
322 gdb::unique_xmalloc_ptr
<gdb_byte
> buffer (
323 (gdb_byte
*)xmalloc (instruction_size
));
326 = target_read (current_top_target (), TARGET_OBJECT_CODE_MEMORY
, NULL
,
327 buffer
.get (), memaddr
, instruction_size
);
328 if (instruction_size
== TARGET_XFER_E_IO
|| instruction_size
== 0)
330 (*di
->memory_error_func
) (-1, memaddr
, di
);
334 amd_dbgapi_architecture_id_t architecture_id
;
335 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (self
->arch ())->mach
,
337 != AMD_DBGAPI_STATUS_SUCCESS
)
340 char *instruction_text
= nullptr;
341 amd_dbgapi_global_address_t
*operands
= nullptr;
342 amd_dbgapi_size_t operand_count
= 0;
344 if (amd_dbgapi_disassemble_instruction (
345 architecture_id
, static_cast<amd_dbgapi_global_address_t
> (memaddr
),
346 &instruction_size
, buffer
.get (), &instruction_text
, &operand_count
,
348 != AMD_DBGAPI_STATUS_SUCCESS
)
351 if (amd_dbgapi_architecture_get_info (
353 AMD_DBGAPI_ARCHITECTURE_INFO_MINIMUM_INSTRUCTION_ALIGNMENT
,
354 sizeof (alignment
), &alignment
)
355 != AMD_DBGAPI_STATUS_SUCCESS
)
356 error (_ ("amd_dbgapi_architecture_get_info failed"));
358 (*di
->fprintf_func
) (di
->stream
, "<illegal instruction>");
359 /* Skip to the next valid instruction address. */
360 return align_up (memaddr
+ 1, alignment
) - memaddr
;
363 /* Print the instruction. */
364 (*di
->fprintf_func
) (di
->stream
, "%s", instruction_text
);
366 /* Print the operands. */
367 for (size_t i
= 0; i
< operand_count
; ++i
)
369 (*di
->fprintf_func
) (di
->stream
, (i
== 0) ? " # " : ", ");
370 (*di
->print_address_func
) (static_cast<bfd_vma
> (operands
[i
]), di
);
373 /* Free the memory allocated by the amd-dbgapi. */
374 xfree (instruction_text
);
377 return static_cast<int> (instruction_size
);
381 amdgcn_skip_prologue (struct gdbarch
*gdbarch
, CORE_ADDR start_pc
)
385 /* See if we can determine the end of the prologue via the symbol table.
386 If so, then return either PC, or the PC after the prologue, whichever
388 if (find_pc_partial_function (start_pc
, NULL
, &func_addr
, NULL
))
390 CORE_ADDR post_prologue_pc
391 = skip_prologue_using_sal (gdbarch
, func_addr
);
392 struct compunit_symtab
*cust
= find_pc_compunit_symtab (func_addr
);
394 /* Clang always emits a line note before the prologue and another
395 one after. We trust clang to emit usable line notes. */
397 && (cust
!= NULL
&& COMPUNIT_PRODUCER (cust
) != NULL
398 && startswith (COMPUNIT_PRODUCER (cust
), "clang ")))
399 return std::max (start_pc
, post_prologue_pc
);
402 /* Can't determine prologue from the symbol table, need to examine
408 static struct gdbarch
*
409 amdgcn_gdbarch_init (struct gdbarch_info info
, struct gdbarch_list
*arches
)
411 /* If there is already a candidate, use it. */
412 arches
= gdbarch_list_lookup_by_info (arches
, &info
);
414 return arches
->gdbarch
;
416 struct gdbarch_deleter
419 operator() (struct gdbarch
*gdbarch
) const
421 gdbarch_free (gdbarch
);
425 /* Allocate space for the new architecture. */
426 std::unique_ptr
<struct gdbarch_tdep
> tdep (new struct gdbarch_tdep
);
427 std::unique_ptr
<struct gdbarch
, gdbarch_deleter
> gdbarch_u (
428 gdbarch_alloc (&info
, tdep
.get ()));
430 struct gdbarch
*gdbarch
= gdbarch_u
.get ();
433 set_gdbarch_char_signed (gdbarch
, 0);
434 set_gdbarch_ptr_bit (gdbarch
, 64);
435 set_gdbarch_addr_bit (gdbarch
, 64);
436 set_gdbarch_short_bit (gdbarch
, 16);
437 set_gdbarch_int_bit (gdbarch
, 32);
438 set_gdbarch_long_bit (gdbarch
, 64);
439 set_gdbarch_long_long_bit (gdbarch
, 64);
440 set_gdbarch_float_bit (gdbarch
, 32);
441 set_gdbarch_double_bit (gdbarch
, 64);
442 set_gdbarch_long_double_bit (gdbarch
, 128);
443 set_gdbarch_float_format (gdbarch
, floatformats_ieee_single
);
444 set_gdbarch_double_format (gdbarch
, floatformats_ieee_double
);
445 set_gdbarch_long_double_format (gdbarch
, floatformats_ieee_double
);
447 /* Frame Interpretation. */
448 set_gdbarch_skip_prologue (gdbarch
, amdgcn_skip_prologue
);
449 set_gdbarch_inner_than (gdbarch
, core_addr_lessthan
);
450 dwarf2_append_unwinders (gdbarch
);
451 frame_unwind_append_unwinder (gdbarch
, &amdgcn_frame_unwind
);
452 set_gdbarch_dummy_id (gdbarch
, amdgcn_dummy_id
);
454 /* Registers and Memory. */
455 amd_dbgapi_architecture_id_t architecture_id
;
456 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch
)->mach
,
458 != AMD_DBGAPI_STATUS_SUCCESS
)
461 size_t register_class_count
;
462 amd_dbgapi_register_class_id_t
*register_class_ids
;
464 if (amd_dbgapi_architecture_register_class_list (
465 architecture_id
, ®ister_class_count
, ®ister_class_ids
)
466 != AMD_DBGAPI_STATUS_SUCCESS
)
469 /* Add register groups. */
470 reggroup_add (gdbarch
, all_reggroup
);
472 for (size_t i
= 0; i
< register_class_count
; ++i
)
475 if (amd_dbgapi_architecture_register_class_get_info (
476 architecture_id
, register_class_ids
[i
],
477 AMD_DBGAPI_REGISTER_CLASS_INFO_NAME
, sizeof (bytes
), &bytes
)
478 != AMD_DBGAPI_STATUS_SUCCESS
)
481 gdb::unique_xmalloc_ptr
<char> name (bytes
);
483 auto inserted
= tdep
->register_class_map
.emplace (name
.get (),
484 register_class_ids
[i
]);
486 if (!inserted
.second
)
489 /* Allocate the reggroup in the gdbarch. */
490 auto *group
= reggroup_gdbarch_new (gdbarch
, name
.get (), USER_REGGROUP
);
493 tdep
->register_class_map
.erase (inserted
.first
);
497 reggroup_add (gdbarch
, group
);
499 xfree (register_class_ids
);
502 size_t register_count
;
503 amd_dbgapi_register_id_t
*register_ids
;
505 if (amd_dbgapi_architecture_register_list (architecture_id
, ®ister_count
,
507 != AMD_DBGAPI_STATUS_SUCCESS
)
510 tdep
->register_ids
.insert (tdep
->register_ids
.end (), ®ister_ids
[0],
511 ®ister_ids
[register_count
]);
513 set_gdbarch_num_regs (gdbarch
, register_count
);
514 set_gdbarch_num_pseudo_regs (gdbarch
, 0);
515 xfree (register_ids
);
517 tdep
->register_names
.resize (register_count
);
518 for (size_t i
= 0; i
< register_count
; ++i
)
520 if (!tdep
->regnum_map
.emplace (tdep
->register_ids
[i
], i
).second
)
524 if (amd_dbgapi_architecture_register_get_info (
525 architecture_id
, tdep
->register_ids
[i
],
526 AMD_DBGAPI_REGISTER_INFO_NAME
, sizeof (bytes
), &bytes
)
527 != AMD_DBGAPI_STATUS_SUCCESS
)
530 tdep
->register_names
[i
] = bytes
;
534 amd_dbgapi_register_id_t pc_register_id
;
535 if (amd_dbgapi_architecture_get_info (
536 architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_PC_REGISTER
,
537 sizeof (pc_register_id
), &pc_register_id
)
538 != AMD_DBGAPI_STATUS_SUCCESS
)
541 set_gdbarch_pc_regnum (gdbarch
, tdep
->regnum_map
[pc_register_id
]);
542 set_gdbarch_ps_regnum (gdbarch
, -1);
543 set_gdbarch_sp_regnum (gdbarch
, -1);
544 set_gdbarch_fp0_regnum (gdbarch
, -1);
546 set_gdbarch_dwarf2_reg_to_regnum (gdbarch
, amdgcn_dwarf_reg_to_regnum
);
548 /* Register Representation. */
549 set_gdbarch_register_name (gdbarch
, amdgcn_register_name
);
550 set_gdbarch_register_type (gdbarch
, amdgcn_register_type
);
551 set_gdbarch_register_reggroup_p (gdbarch
, amdgcn_register_reggroup_p
);
554 set_gdbarch_print_insn (gdbarch
, print_insn_amdgcn
);
556 /* Displaced stepping. */
557 set_gdbarch_displaced_step_location (gdbarch
,
558 amdgcn_rocm_displaced_step_location
);
560 set_gdbarch_displaced_step_copy_insn (gdbarch
,
561 amdgcn_rocm_displaced_step_copy_insn
);
562 set_gdbarch_displaced_step_fixup (gdbarch
, amdgcn_rocm_displaced_step_fixup
);
565 amd_dbgapi_size_t max_insn_length
= 0;
566 if (amd_dbgapi_architecture_get_info (
568 AMD_DBGAPI_ARCHITECTURE_INFO_LARGEST_INSTRUCTION_SIZE
,
569 sizeof (max_insn_length
), &max_insn_length
)
570 != AMD_DBGAPI_STATUS_SUCCESS
)
571 error (_ ("amd_dbgapi_architecture_get_info failed"));
573 set_gdbarch_max_insn_length (gdbarch
, max_insn_length
);
575 if (amd_dbgapi_architecture_get_info (
577 AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_SIZE
,
578 sizeof (tdep
->breakpoint_instruction_size
),
579 &tdep
->breakpoint_instruction_size
)
580 != AMD_DBGAPI_STATUS_SUCCESS
)
581 error (_ ("amd_dbgapi_architecture_get_info failed"));
583 gdb_byte
*breakpoint_instruction_bytes
;
584 if (amd_dbgapi_architecture_get_info (
585 architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION
,
586 sizeof (breakpoint_instruction_bytes
), &breakpoint_instruction_bytes
)
587 != AMD_DBGAPI_STATUS_SUCCESS
)
588 error (_ ("amd_dbgapi_architecture_get_info failed"));
590 tdep
->breakpoint_instruction_bytes
.reset (breakpoint_instruction_bytes
);
592 set_gdbarch_breakpoint_kind_from_pc (gdbarch
,
593 amdgcn_breakpoint_kind_from_pc
);
594 set_gdbarch_sw_breakpoint_from_kind (gdbarch
,
595 amdgcn_sw_breakpoint_from_kind
);
598 gdbarch_u
.release ();
603 /* Provide a prototype to silence -Wmissing-prototypes. */
604 extern initialize_file_ftype _initialize_amdgcn_rocm_tdep
;
607 _initialize_amdgcn_rocm_tdep (void)
609 gdbarch_register (bfd_arch_amdgcn
, amdgcn_gdbarch_init
, NULL
);