packaging: Add python3-base dependency
[platform/upstream/gdb.git] / gdb / riscv-none-tdep.c
1 /* Copyright (C) 2020-2023 Free Software Foundation, Inc.
2
3    This file is part of GDB.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 /* This file contain code that is specific for bare-metal RISC-V targets.  */
19
20 #include "defs.h"
21 #include "arch-utils.h"
22 #include "regcache.h"
23 #include "riscv-tdep.h"
24 #include "elf-bfd.h"
25 #include "regset.h"
26 #include "user-regs.h"
27 #include "target-descriptions.h"
28
29 #ifdef HAVE_ELF
30 #include "elf-none-tdep.h"
31 #endif
32
33 /* Define the general register mapping.  This follows the same format as
34    the RISC-V linux corefile.  The linux kernel puts the PC at offset 0,
35    gdb puts it at offset 32.  Register x0 is always 0 and can be ignored.
36    Registers x1 to x31 are in the same place.  */
37
38 static const struct regcache_map_entry riscv_gregmap[] =
39 {
40   { 1,  RISCV_PC_REGNUM, 0 },
41   { 31, RISCV_RA_REGNUM, 0 }, /* x1 to x31 */
42   { 0 }
43 };
44
45 /* Define the FP register mapping.  This follows the same format as the
46    RISC-V linux corefile.  The kernel puts the 32 FP regs first, and then
47    FCSR.  */
48
49 static const struct regcache_map_entry riscv_fregmap[] =
50 {
51   { 32, RISCV_FIRST_FP_REGNUM, 0 },
52   { 1, RISCV_CSR_FCSR_REGNUM, 4 },      /* Always stored as 4-bytes.  */
53   { 0 }
54 };
55
56 /* Define the general register regset.  */
57
58 static const struct regset riscv_gregset =
59 {
60   riscv_gregmap, riscv_supply_regset, regcache_collect_regset
61 };
62
63 /* Define the FP register regset.  */
64
65 static const struct regset riscv_fregset =
66 {
67   riscv_fregmap, riscv_supply_regset, regcache_collect_regset
68 };
69
70 /* Define the CSR regset, this is not constant as the regmap field is
71    updated dynamically based on the current target description.  */
72
73 static struct regset riscv_csrset =
74 {
75   nullptr, regcache_supply_regset, regcache_collect_regset
76 };
77
78 /* Update the regmap field of RISCV_CSRSET based on the CSRs available in
79    the current target description.  */
80
81 static void
82 riscv_update_csrmap (struct gdbarch *gdbarch,
83                      const struct tdesc_feature *feature_csr)
84 {
85   int i = 0;
86
87   /* Release any previously defined map.  */
88   delete[] ((struct regcache_map_entry *) riscv_csrset.regmap);
89
90   /* Now create a register map for every csr found in the target
91      description.  */
92   struct regcache_map_entry *riscv_csrmap
93     = new struct regcache_map_entry[feature_csr->registers.size() + 1];
94   for (auto &csr : feature_csr->registers)
95     {
96       int regnum = user_reg_map_name_to_regnum (gdbarch, csr->name.c_str(),
97                                                 csr->name.length());
98       riscv_csrmap[i++] = {1, regnum, 0};
99     }
100
101   /* Mark the end of the array.  */
102   riscv_csrmap[i] = {0};
103   riscv_csrset.regmap = riscv_csrmap;
104 }
105
106 /* Implement the "iterate_over_regset_sections" gdbarch method.  */
107
108 static void
109 riscv_iterate_over_regset_sections (struct gdbarch *gdbarch,
110                                     iterate_over_regset_sections_cb *cb,
111                                     void *cb_data,
112                                     const struct regcache *regcache)
113 {
114   /* Write out the GPRs.  */
115   int sz = 32 * riscv_isa_xlen (gdbarch);
116   cb (".reg", sz, sz, &riscv_gregset, NULL, cb_data);
117
118   /* Write out the FPRs, but only if present.  */
119   if (riscv_isa_flen (gdbarch) > 0)
120     {
121       sz = (32 * riscv_isa_flen (gdbarch)
122             + register_size (gdbarch, RISCV_CSR_FCSR_REGNUM));
123       cb (".reg2", sz, sz, &riscv_fregset, NULL, cb_data);
124     }
125
126   /* Read or write the CSRs.  The set of CSRs is defined by the current
127      target description.  The user is responsible for ensuring that the
128      same target description is in use when reading the core file as was
129      in use when writing the core file.  */
130   const struct target_desc *tdesc = gdbarch_target_desc (gdbarch);
131
132   /* Do not dump/load any CSRs if there is no target description or the target
133      description does not contain any CSRs.  */
134   if (tdesc != nullptr)
135     {
136       const struct tdesc_feature *feature_csr
137         = tdesc_find_feature (tdesc, riscv_feature_name_csr);
138       if (feature_csr != nullptr && feature_csr->registers.size () > 0)
139         {
140           riscv_update_csrmap (gdbarch, feature_csr);
141           cb (".reg-riscv-csr",
142               (feature_csr->registers.size() * riscv_isa_xlen (gdbarch)),
143               (feature_csr->registers.size() * riscv_isa_xlen (gdbarch)),
144               &riscv_csrset, NULL, cb_data);
145         }
146     }
147 }
148
149 /* Initialize RISC-V bare-metal ABI info.  */
150
151 static void
152 riscv_none_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
153 {
154 #ifdef HAVE_ELF
155   elf_none_init_abi (gdbarch);
156 #endif
157
158   /* Iterate over registers for reading and writing bare metal RISC-V core
159      files.  */
160   set_gdbarch_iterate_over_regset_sections
161     (gdbarch, riscv_iterate_over_regset_sections);
162
163 }
164
165 /* Initialize RISC-V bare-metal target support.  */
166
167 void _initialize_riscv_none_tdep ();
168 void
169 _initialize_riscv_none_tdep ()
170 {
171   gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_NONE,
172                           riscv_none_init_abi);
173 }