Merge branch 'master' into merge-job
[deliverable/binutils-gdb.git] / gdb / amdgcn-rocm-tdep.c
CommitLineData
5922befa
LM
1/* Target-dependent code for the ROCm amdgcn architecture.
2
3 Copyright (C) 2019 Free Software Foundation, Inc.
4 Copyright (C) 2019 Advanced Micro Devices, Inc. All rights reserved.
5
6 This file is part of GDB.
7
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.
12
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.
17
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/>. */
20
21#include "defs.h"
22
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"
28#include "gdbarch.h"
29#include "inferior.h"
30#include "osabi.h"
31#include "reggroups.h"
32#include "rocm-tdep.h"
33
34bool
35rocm_is_amdgcn_gdbarch (struct gdbarch *arch)
36{
37 return (gdbarch_bfd_arch_info (arch)->arch == bfd_arch_amdgcn);
38}
39
40/* Return the name of register REGNUM. */
41static const char *
42amdgcn_register_name (struct gdbarch *gdbarch, int regnum)
43{
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);
47
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)
53 return "";
54
55 return tdep->register_names[regnum].c_str ();
56}
57
58static int
59amdgcn_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
60{
61 amd_dbgapi_architecture_id_t architecture_id;
62 amd_dbgapi_register_id_t register_id;
63
64 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch)->mach,
65 &architecture_id)
66 != AMD_DBGAPI_STATUS_SUCCESS)
67 return -1;
68
69 if (amd_dbgapi_dwarf_register_to_register (architecture_id, reg,
70 &register_id)
71 != AMD_DBGAPI_STATUS_SUCCESS)
72 return -1;
73
74 return gdbarch_tdep (gdbarch)->regnum_map[register_id];
75}
76
77static struct type *
78gdb_type_from_type_name (struct gdbarch *gdbarch, const std::string &type_name)
79{
80 size_t pos;
81
82 /* vector types. */
83 if ((pos = type_name.find_last_of ('[')) != std::string::npos)
84 {
85 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
86
87 auto it = tdep->vector_type_map.find (type_name);
88 if (it != tdep->vector_type_map.end ())
89 return it->second;
90
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)));
94
95 tdep->vector_type_map[type_name] = vector_type;
96 return vector_type;
97 }
98 /* scalar types. */
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;
113
114 return builtin_type (gdbarch)->builtin_void;
115}
116
117static struct type *
118amdgcn_register_type (struct gdbarch *gdbarch, int regnum)
119{
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);
123
124 char *bytes;
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)
129 {
130 std::string type_name (bytes);
131 xfree (bytes);
132
133 return gdb_type_from_type_name (gdbarch, type_name);
134 }
135
136 return builtin_type (gdbarch)->builtin_void;
137}
138
139static int
140amdgcn_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
141 struct reggroup *group)
142{
143 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
144 const char *name = reggroup_name (group);
145
146 auto it = tdep->register_class_map.find (name);
147 if (it == tdep->register_class_map.end ())
148 return group == all_reggroup;
149
150 amd_dbgapi_architecture_id_t architecture_id;
151
152 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch)->mach,
153 &architecture_id)
154 != AMD_DBGAPI_STATUS_SUCCESS)
155 return group == all_reggroup;
156
157 amd_dbgapi_register_class_state_t state;
158
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;
163
164 return state == AMD_DBGAPI_REGISTER_CLASS_STATE_MEMBER
165 || group == all_reggroup;
166}
167
168static int
169amdgcn_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *)
170{
171 return gdbarch_tdep (gdbarch)->breakpoint_instruction_size;
172}
173
174static const gdb_byte *
175amdgcn_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
176{
177 *size = kind;
178 return gdbarch_tdep (gdbarch)->breakpoint_instruction_bytes.get ();
179}
180
181struct amdgcn_frame_cache
182{
183 CORE_ADDR base;
184 CORE_ADDR pc;
185};
186
187static struct amdgcn_frame_cache *
188amdgcn_frame_cache (struct frame_info *this_frame, void **this_cache)
189{
190 if (*this_cache)
191 return (struct amdgcn_frame_cache *)*this_cache;
192
193 struct amdgcn_frame_cache *cache
194 = FRAME_OBSTACK_ZALLOC (struct amdgcn_frame_cache);
195 (*this_cache) = cache;
196
197 cache->pc = get_frame_func (this_frame);
198 cache->base = 0;
199
200 return cache;
201}
202
203static void
204amdgcn_frame_this_id (struct frame_info *this_frame, void **this_cache,
205 struct frame_id *this_id)
206{
207 struct amdgcn_frame_cache *cache
208 = amdgcn_frame_cache (this_frame, this_cache);
209
210 if (get_frame_type (this_frame) == INLINE_FRAME)
211 (*this_id) = frame_id_build (cache->base, cache->pc);
212 else
213 (*this_id) = outer_frame_id;
214
215 if (frame_debug)
216 {
217 fprintf_unfiltered (
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");
222 }
223
224 return;
225}
226
227static struct frame_id
228amdgcn_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
229{
230 return frame_id_build (0, get_frame_pc (this_frame));
231}
232
233static struct value *
234amdgcn_frame_prev_register (struct frame_info *this_frame, void **this_cache,
235 int regnum)
236{
237 return frame_unwind_got_register (this_frame, regnum, regnum);
238}
239
240static const struct frame_unwind amdgcn_frame_unwind = {
241 NORMAL_FRAME,
242 default_frame_unwind_stop_reason,
243 amdgcn_frame_this_id,
244 amdgcn_frame_prev_register,
245 NULL,
246 default_frame_sniffer,
247 NULL,
248 NULL,
249};
250
251struct rocm_displaced_step_closure : public displaced_step_closure
252{
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;
256};
257
258static CORE_ADDR
259amdgcn_rocm_displaced_step_location (struct gdbarch *gdbarch)
260{
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)));
264
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))
268 return 0;
269
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)
275 return 0;
276
277 return stepping_id.handle;
278}
279
280static struct displaced_step_closure *
281amdgcn_rocm_displaced_step_copy_insn (struct gdbarch *gdbarch, CORE_ADDR from,
282 CORE_ADDR to, struct regcache *regcache)
283{
284 rocm_displaced_step_closure *closure = new rocm_displaced_step_closure;
285
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 };
289
290 return closure;
291}
292
293static void
294amdgcn_rocm_displaced_step_fixup (struct gdbarch *gdbarch,
295 struct displaced_step_closure *closure_,
296 CORE_ADDR from, CORE_ADDR to,
297 struct regcache *regcache)
298{
299 rocm_displaced_step_closure *closure
300 = reinterpret_cast<rocm_displaced_step_closure *> (closure_);
301
302 amd_dbgapi_status_t status = amd_dbgapi_displaced_stepping_complete (
303 closure->process_id, closure->wave_id, closure->displaced_stepping_id);
304
305 if (status != AMD_DBGAPI_STATUS_SUCCESS)
306 error (_ ("amd_dbgapi_displaced_stepping_complete failed (rc=%d"), status);
307
308 /* We may have written some registers, so flush the register cache. */
309 registers_changed_ptid (regcache->ptid ());
310}
311
312static int
313print_insn_amdgcn (bfd_vma memaddr, struct disassemble_info *di)
314{
315 gdb_disassembler *self
316 = static_cast<gdb_disassembler *> (di->application_data);
317
318 /* Try to read at most instruction_size bytes. */
319
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));
323
324 instruction_size
325 = target_read (current_top_target (), TARGET_OBJECT_MEMORY, NULL,
326 buffer.get (), memaddr, instruction_size);
327 if (!instruction_size)
328 {
329 (*di->memory_error_func) (-1, memaddr, di);
330 return -1;
331 }
332
333 amd_dbgapi_architecture_id_t architecture_id;
334 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (self->arch ())->mach,
335 &architecture_id)
336 != AMD_DBGAPI_STATUS_SUCCESS)
337 return -1;
338
339 char *instruction_text = nullptr;
340 amd_dbgapi_global_address_t *operands = nullptr;
341 amd_dbgapi_size_t operand_count = 0;
342
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,
346 &operands)
347 != AMD_DBGAPI_STATUS_SUCCESS)
348 {
349 size_t alignment;
350 if (amd_dbgapi_architecture_get_info (
351 architecture_id,
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"));
356
357 (*di->fprintf_func) (di->stream, "<illegal instruction>");
358 /* Skip to the next valid instruction address. */
359 return align_up (memaddr + 1, alignment) - memaddr;
360 }
361
362 /* Print the instruction. */
363 (*di->fprintf_func) (di->stream, "%s", instruction_text);
364
365 /* Print the operands. */
366 for (size_t i = 0; i < operand_count; ++i)
367 {
368 (*di->fprintf_func) (di->stream, (i == 0) ? " # " : ", ");
369 (*di->print_address_func) (static_cast<bfd_vma> (operands[i]), di);
370 }
371
372 /* Free the memory allocated by the amd-dbgapi. */
373 xfree (instruction_text);
374 xfree (operands);
375
376 return static_cast<int> (instruction_size);
377}
378
379static CORE_ADDR
380amdgcn_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
381{
382 CORE_ADDR func_addr;
383
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
386 is greater. */
387 if (find_pc_partial_function (start_pc, NULL, &func_addr, NULL))
388 {
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);
392
393 /* Clang always emits a line note before the prologue and another
394 one after. We trust clang to emit usable line notes. */
395 if (post_prologue_pc
396 && (cust != NULL && COMPUNIT_PRODUCER (cust) != NULL
397 && startswith (COMPUNIT_PRODUCER (cust), "clang ")))
398 return std::max (start_pc, post_prologue_pc);
399 }
400
401 /* Can't determine prologue from the symbol table, need to examine
402 instructions. */
403
404 return start_pc;
405}
406
407static struct gdbarch *
408amdgcn_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
409{
410 /* If there is already a candidate, use it. */
411 arches = gdbarch_list_lookup_by_info (arches, &info);
412 if (arches != NULL)
413 return arches->gdbarch;
414
415 struct gdbarch_deleter
416 {
417 void
418 operator() (struct gdbarch *gdbarch) const
419 {
420 gdbarch_free (gdbarch);
421 }
422 };
423
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 ()));
428
429 struct gdbarch *gdbarch = gdbarch_u.get ();
430
431 /* Data types. */
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);
445
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);
452
453 /* Registers and Memory. */
454 amd_dbgapi_architecture_id_t architecture_id;
455 if (amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch)->mach,
456 &architecture_id)
457 != AMD_DBGAPI_STATUS_SUCCESS)
458 return nullptr;
459
460 size_t register_class_count;
461 amd_dbgapi_register_class_id_t *register_class_ids;
462
463 if (amd_dbgapi_architecture_register_class_list (
464 architecture_id, &register_class_count, &register_class_ids)
465 != AMD_DBGAPI_STATUS_SUCCESS)
466 return nullptr;
467
468 /* Add register groups. */
469 reggroup_add (gdbarch, all_reggroup);
470
471 for (size_t i = 0; i < register_class_count; ++i)
472 {
473 char *bytes;
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)
478 continue;
479
480 gdb::unique_xmalloc_ptr<char> name (bytes);
481
482 auto inserted = tdep->register_class_map.emplace (name.get (),
483 register_class_ids[i]);
484
485 if (!inserted.second)
486 continue;
487
488 /* Allocate the reggroup in the gdbarch. */
489 auto *group = reggroup_gdbarch_new (gdbarch, name.get (), USER_REGGROUP);
490 if (!group)
491 {
492 tdep->register_class_map.erase (inserted.first);
493 continue;
494 }
495
496 reggroup_add (gdbarch, group);
497 }
498 xfree (register_class_ids);
499
500 /* Add registers. */
501 size_t register_count;
502 amd_dbgapi_register_id_t *register_ids;
503
504 if (amd_dbgapi_architecture_register_list (architecture_id, &register_count,
505 &register_ids)
506 != AMD_DBGAPI_STATUS_SUCCESS)
507 return nullptr;
508
509 tdep->register_ids.insert (tdep->register_ids.end (), &register_ids[0],
510 &register_ids[register_count]);
511
512 set_gdbarch_num_regs (gdbarch, register_count);
513 set_gdbarch_num_pseudo_regs (gdbarch, 0);
514 xfree (register_ids);
515
516 tdep->register_names.resize (register_count);
517 for (size_t i = 0; i < register_count; ++i)
518 {
519 if (!tdep->regnum_map.emplace (tdep->register_ids[i], i).second)
520 return nullptr;
521
522 char *bytes;
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)
527 continue;
528
529 tdep->register_names[i] = bytes;
530 xfree (bytes);
531 }
532
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)
538 return nullptr;
539
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);
544
545 set_gdbarch_dwarf2_reg_to_regnum (gdbarch, amdgcn_dwarf_reg_to_regnum);
546
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);
551
552 /* Disassembly. */
553 set_gdbarch_print_insn (gdbarch, print_insn_amdgcn);
554
555 /* Displaced stepping. */
556 set_gdbarch_displaced_step_location (gdbarch,
557 amdgcn_rocm_displaced_step_location);
558
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);
562
563 /* Instructions. */
564 amd_dbgapi_size_t max_insn_length = 0;
565 if (amd_dbgapi_architecture_get_info (
566 architecture_id,
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"));
571
572 set_gdbarch_max_insn_length (gdbarch, max_insn_length);
573
574 if (amd_dbgapi_architecture_get_info (
575 architecture_id,
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"));
581
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"));
589
590 tdep->breakpoint_instruction_bytes.reset (breakpoint_instruction_bytes);
591
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);
596
597 tdep.release ();
598 gdbarch_u.release ();
599
600 return gdbarch;
601}
602
603/* Provide a prototype to silence -Wmissing-prototypes. */
604extern initialize_file_ftype _initialize_amdgcn_rocm_tdep;
605
606void
607_initialize_amdgcn_rocm_tdep (void)
608{
609 gdbarch_register (bfd_arch_amdgcn, amdgcn_gdbarch_init, NULL);
610}
This page took 0.04538 seconds and 4 git commands to generate.