1 /* Target-dependent code for the ROCm amdgcn architecture.
3 Copyright (C) 2019 Free Software Foundation, Inc.
4 Copyright (C) 2019 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"), status
);
308 /* We may have written some registers, so flush the register cache. */
309 registers_changed_ptid (regcache
->ptid ());
313 print_insn_amdgcn (bfd_vma memaddr
, struct disassemble_info
*di
)
315 gdb_disassembler
*self
316 = static_cast<gdb_disassembler
*> (di
->application_data
);
318 /* Try to read at most instruction_size bytes. */
320 amd_dbgapi_size_t instruction_size
= gdbarch_max_insn_length (self
->arch ());
321 gdb::unique_xmalloc_ptr
<gdb_byte
> buffer (
322 (gdb_byte
*)xmalloc (instruction_size
));
325 = target_read (current_top_target (), TARGET_OBJECT_MEMORY
, NULL
,
326 buffer
.get (), memaddr
, instruction_size
);
327 if (!instruction_size
)
329 (*di
->memory_error_func
) (-1, memaddr
, di
);
333 amd_dbgapi_architecture_id_t architecture_id
;
334 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (self
->arch ())->mach
,
336 != AMD_DBGAPI_STATUS_SUCCESS
)
339 char *instruction_text
= nullptr;
340 amd_dbgapi_global_address_t
*operands
= nullptr;
341 amd_dbgapi_size_t operand_count
= 0;
343 if (amd_dbgapi_disassemble_instruction (
344 architecture_id
, static_cast<amd_dbgapi_global_address_t
> (memaddr
),
345 &instruction_size
, buffer
.get (), &instruction_text
, &operand_count
,
347 != AMD_DBGAPI_STATUS_SUCCESS
)
350 if (amd_dbgapi_architecture_get_info (
352 AMD_DBGAPI_ARCHITECTURE_INFO_MINIMUM_INSTRUCTION_ALIGNMENT
,
353 sizeof (alignment
), &alignment
)
354 != AMD_DBGAPI_STATUS_SUCCESS
)
355 error (_ ("amd_dbgapi_architecture_get_info failed"));
357 (*di
->fprintf_func
) (di
->stream
, "<illegal instruction>");
358 /* Skip to the next valid instruction address. */
359 return align_up (memaddr
+ 1, alignment
) - memaddr
;
362 /* Print the instruction. */
363 (*di
->fprintf_func
) (di
->stream
, "%s", instruction_text
);
365 /* Print the operands. */
366 for (size_t i
= 0; i
< operand_count
; ++i
)
368 (*di
->fprintf_func
) (di
->stream
, (i
== 0) ? " # " : ", ");
369 (*di
->print_address_func
) (static_cast<bfd_vma
> (operands
[i
]), di
);
372 /* Free the memory allocated by the amd-dbgapi. */
373 xfree (instruction_text
);
376 return static_cast<int> (instruction_size
);
380 amdgcn_skip_prologue (struct gdbarch
*gdbarch
, CORE_ADDR start_pc
)
384 /* See if we can determine the end of the prologue via the symbol table.
385 If so, then return either PC, or the PC after the prologue, whichever
387 if (find_pc_partial_function (start_pc
, NULL
, &func_addr
, NULL
))
389 CORE_ADDR post_prologue_pc
390 = skip_prologue_using_sal (gdbarch
, func_addr
);
391 struct compunit_symtab
*cust
= find_pc_compunit_symtab (func_addr
);
393 /* Clang always emits a line note before the prologue and another
394 one after. We trust clang to emit usable line notes. */
396 && (cust
!= NULL
&& COMPUNIT_PRODUCER (cust
) != NULL
397 && startswith (COMPUNIT_PRODUCER (cust
), "clang ")))
398 return std::max (start_pc
, post_prologue_pc
);
401 /* Can't determine prologue from the symbol table, need to examine
407 static struct gdbarch
*
408 amdgcn_gdbarch_init (struct gdbarch_info info
, struct gdbarch_list
*arches
)
410 /* If there is already a candidate, use it. */
411 arches
= gdbarch_list_lookup_by_info (arches
, &info
);
413 return arches
->gdbarch
;
415 struct gdbarch_deleter
418 operator() (struct gdbarch
*gdbarch
) const
420 gdbarch_free (gdbarch
);
424 /* Allocate space for the new architecture. */
425 std::unique_ptr
<struct gdbarch_tdep
> tdep (new struct gdbarch_tdep
);
426 std::unique_ptr
<struct gdbarch
, gdbarch_deleter
> gdbarch_u (
427 gdbarch_alloc (&info
, tdep
.get ()));
429 struct gdbarch
*gdbarch
= gdbarch_u
.get ();
432 set_gdbarch_char_signed (gdbarch
, 0);
433 set_gdbarch_ptr_bit (gdbarch
, 64);
434 set_gdbarch_addr_bit (gdbarch
, 64);
435 set_gdbarch_short_bit (gdbarch
, 16);
436 set_gdbarch_int_bit (gdbarch
, 32);
437 set_gdbarch_long_bit (gdbarch
, 64);
438 set_gdbarch_long_long_bit (gdbarch
, 64);
439 set_gdbarch_float_bit (gdbarch
, 32);
440 set_gdbarch_double_bit (gdbarch
, 64);
441 set_gdbarch_long_double_bit (gdbarch
, 128);
442 set_gdbarch_float_format (gdbarch
, floatformats_ieee_single
);
443 set_gdbarch_double_format (gdbarch
, floatformats_ieee_double
);
444 set_gdbarch_long_double_format (gdbarch
, floatformats_ieee_double
);
446 /* Frame Interpretation. */
447 set_gdbarch_skip_prologue (gdbarch
, amdgcn_skip_prologue
);
448 set_gdbarch_inner_than (gdbarch
, core_addr_lessthan
);
449 dwarf2_append_unwinders (gdbarch
);
450 frame_unwind_append_unwinder (gdbarch
, &amdgcn_frame_unwind
);
451 set_gdbarch_dummy_id (gdbarch
, amdgcn_dummy_id
);
453 /* Registers and Memory. */
454 amd_dbgapi_architecture_id_t architecture_id
;
455 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch
)->mach
,
457 != AMD_DBGAPI_STATUS_SUCCESS
)
460 size_t register_class_count
;
461 amd_dbgapi_register_class_id_t
*register_class_ids
;
463 if (amd_dbgapi_architecture_register_class_list (
464 architecture_id
, ®ister_class_count
, ®ister_class_ids
)
465 != AMD_DBGAPI_STATUS_SUCCESS
)
468 /* Add register groups. */
469 reggroup_add (gdbarch
, all_reggroup
);
471 for (size_t i
= 0; i
< register_class_count
; ++i
)
474 if (amd_dbgapi_architecture_register_class_get_info (
475 architecture_id
, register_class_ids
[i
],
476 AMD_DBGAPI_REGISTER_CLASS_INFO_NAME
, sizeof (bytes
), &bytes
)
477 != AMD_DBGAPI_STATUS_SUCCESS
)
480 gdb::unique_xmalloc_ptr
<char> name (bytes
);
482 auto inserted
= tdep
->register_class_map
.emplace (name
.get (),
483 register_class_ids
[i
]);
485 if (!inserted
.second
)
488 /* Allocate the reggroup in the gdbarch. */
489 auto *group
= reggroup_gdbarch_new (gdbarch
, name
.get (), USER_REGGROUP
);
492 tdep
->register_class_map
.erase (inserted
.first
);
496 reggroup_add (gdbarch
, group
);
498 xfree (register_class_ids
);
501 size_t register_count
;
502 amd_dbgapi_register_id_t
*register_ids
;
504 if (amd_dbgapi_architecture_register_list (architecture_id
, ®ister_count
,
506 != AMD_DBGAPI_STATUS_SUCCESS
)
509 tdep
->register_ids
.insert (tdep
->register_ids
.end (), ®ister_ids
[0],
510 ®ister_ids
[register_count
]);
512 set_gdbarch_num_regs (gdbarch
, register_count
);
513 set_gdbarch_num_pseudo_regs (gdbarch
, 0);
514 xfree (register_ids
);
516 tdep
->register_names
.resize (register_count
);
517 for (size_t i
= 0; i
< register_count
; ++i
)
519 if (!tdep
->regnum_map
.emplace (tdep
->register_ids
[i
], i
).second
)
523 if (amd_dbgapi_architecture_register_get_info (
524 architecture_id
, tdep
->register_ids
[i
],
525 AMD_DBGAPI_REGISTER_INFO_NAME
, sizeof (bytes
), &bytes
)
526 != AMD_DBGAPI_STATUS_SUCCESS
)
529 tdep
->register_names
[i
] = bytes
;
533 amd_dbgapi_register_id_t pc_register_id
;
534 if (amd_dbgapi_architecture_get_info (
535 architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_PC_REGISTER
,
536 sizeof (pc_register_id
), &pc_register_id
)
537 != AMD_DBGAPI_STATUS_SUCCESS
)
540 set_gdbarch_pc_regnum (gdbarch
, tdep
->regnum_map
[pc_register_id
]);
541 set_gdbarch_ps_regnum (gdbarch
, -1);
542 set_gdbarch_sp_regnum (gdbarch
, -1);
543 set_gdbarch_fp0_regnum (gdbarch
, -1);
545 set_gdbarch_dwarf2_reg_to_regnum (gdbarch
, amdgcn_dwarf_reg_to_regnum
);
547 /* Register Representation. */
548 set_gdbarch_register_name (gdbarch
, amdgcn_register_name
);
549 set_gdbarch_register_type (gdbarch
, amdgcn_register_type
);
550 set_gdbarch_register_reggroup_p (gdbarch
, amdgcn_register_reggroup_p
);
553 set_gdbarch_print_insn (gdbarch
, print_insn_amdgcn
);
555 /* Displaced stepping. */
556 set_gdbarch_displaced_step_location (gdbarch
,
557 amdgcn_rocm_displaced_step_location
);
559 set_gdbarch_displaced_step_copy_insn (gdbarch
,
560 amdgcn_rocm_displaced_step_copy_insn
);
561 set_gdbarch_displaced_step_fixup (gdbarch
, amdgcn_rocm_displaced_step_fixup
);
564 amd_dbgapi_size_t max_insn_length
= 0;
565 if (amd_dbgapi_architecture_get_info (
567 AMD_DBGAPI_ARCHITECTURE_INFO_LARGEST_INSTRUCTION_SIZE
,
568 sizeof (max_insn_length
), &max_insn_length
)
569 != AMD_DBGAPI_STATUS_SUCCESS
)
570 error (_ ("amd_dbgapi_architecture_get_info failed"));
572 set_gdbarch_max_insn_length (gdbarch
, max_insn_length
);
574 if (amd_dbgapi_architecture_get_info (
576 AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_SIZE
,
577 sizeof (tdep
->breakpoint_instruction_size
),
578 &tdep
->breakpoint_instruction_size
)
579 != AMD_DBGAPI_STATUS_SUCCESS
)
580 error (_ ("amd_dbgapi_architecture_get_info failed"));
582 gdb_byte
*breakpoint_instruction_bytes
;
583 if (amd_dbgapi_architecture_get_info (
584 architecture_id
, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION
,
585 sizeof (breakpoint_instruction_bytes
),
586 &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
);