|
1 Support for target descriptions layered on top of sparc32/sparc64 |
|
2 which describe more registers than native ones. |
|
3 Pseudo registers always come after the real registers. |
|
4 One more step forward to modernize sparc tdep's. |
|
5 Submitted to upstream as: |
|
6 https://sourceware.org/bugzilla/show_bug.cgi?id=20936 |
|
7 |
|
8 --- gdb-7.11/gdb/sparc-tdep.c.orig 2016-11-18 06:00:18.299687730 -0800 |
|
9 +++ gdb-7.11/gdb/sparc-tdep.c 2016-11-18 06:01:36.293409472 -0800 |
|
10 @@ -33,6 +33,7 @@ |
|
11 #include "osabi.h" |
|
12 #include "regcache.h" |
|
13 #include "target.h" |
|
14 +#include "target-descriptions.h" |
|
15 #include "value.h" |
|
16 |
|
17 #include "sparc-tdep.h" |
|
18 @@ -295,20 +296,23 @@ |
|
19 } |
|
20 |
|
21 /* Register information. */ |
|
22 +#define SPARC32_FPU_REGISTERS \ |
|
23 + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ |
|
24 + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ |
|
25 + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ |
|
26 + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" |
|
27 +#define SPARC32_CP0_REGISTERS \ |
|
28 + "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" |
|
29 |
|
30 +static const char *sparc_core_register_names[] = { SPARC_CORE_REGISTERS }; |
|
31 +static const char *sparc32_fpu_register_names[] = { SPARC32_FPU_REGISTERS }; |
|
32 +static const char *sparc32_cp0_register_names[] = { SPARC32_CP0_REGISTERS }; |
|
33 + |
|
34 static const char *sparc32_register_names[] = |
|
35 { |
|
36 - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", |
|
37 - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", |
|
38 - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", |
|
39 - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", |
|
40 - |
|
41 - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
|
42 - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", |
|
43 - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", |
|
44 - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", |
|
45 - |
|
46 - "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" |
|
47 + SPARC_CORE_REGISTERS, |
|
48 + SPARC32_FPU_REGISTERS, |
|
49 + SPARC32_CP0_REGISTERS |
|
50 }; |
|
51 |
|
52 /* Total number of registers. */ |
|
53 @@ -327,7 +331,19 @@ |
|
54 #define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names) |
|
55 |
|
56 /* Return the name of register REGNUM. */ |
|
57 +static const char * |
|
58 +sparc32_pseudo_register_name (struct gdbarch *gdbarch, int regnum) |
|
59 +{ |
|
60 + regnum -= gdbarch_num_regs (gdbarch); |
|
61 |
|
62 + if (regnum < SPARC32_NUM_PSEUDO_REGS) |
|
63 + return sparc32_pseudo_register_names[regnum]; |
|
64 + |
|
65 + internal_error (__FILE__, __LINE__, |
|
66 + _("sparc32_pseudo_register_name: bad register number %d"), |
|
67 + regnum); |
|
68 +} |
|
69 + |
|
70 static const char * |
|
71 sparc32_register_name (struct gdbarch *gdbarch, int regnum) |
|
72 { |
|
73 @@ -334,10 +350,10 @@ |
|
74 if (regnum >= 0 && regnum < SPARC32_NUM_REGS) |
|
75 return sparc32_register_names[regnum]; |
|
76 |
|
77 - if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS) |
|
78 - return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS]; |
|
79 + if (regnum >= gdbarch_num_regs (gdbarch)) |
|
80 + return sparc32_pseudo_register_name (gdbarch, regnum); |
|
81 |
|
82 - return NULL; |
|
83 + return tdesc_register_name (gdbarch, regnum); |
|
84 } |
|
85 |
|
86 /* Construct types for ISA-specific registers. */ |
|
87 @@ -399,7 +415,19 @@ |
|
88 |
|
89 /* Return the GDB type object for the "standard" data type of data in |
|
90 register REGNUM. */ |
|
91 +static struct type * |
|
92 +sparc32_pseudo_register_type (struct gdbarch *gdbarch, int regnum) |
|
93 +{ |
|
94 + regnum -= gdbarch_num_regs (gdbarch); |
|
95 |
|
96 + if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM) |
|
97 + return builtin_type (gdbarch)->builtin_double; |
|
98 + |
|
99 + internal_error (__FILE__, __LINE__, |
|
100 + _("sparc32_pseudo_register_type: bad register number %d"), |
|
101 + regnum); |
|
102 +} |
|
103 + |
|
104 static struct type * |
|
105 sparc32_register_type (struct gdbarch *gdbarch, int regnum) |
|
106 { |
|
107 @@ -406,9 +434,6 @@ |
|
108 if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) |
|
109 return builtin_type (gdbarch)->builtin_float; |
|
110 |
|
111 - if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM) |
|
112 - return builtin_type (gdbarch)->builtin_double; |
|
113 - |
|
114 if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM) |
|
115 return builtin_type (gdbarch)->builtin_data_ptr; |
|
116 |
|
117 @@ -421,6 +446,9 @@ |
|
118 if (regnum == SPARC32_FSR_REGNUM) |
|
119 return sparc_fsr_type (gdbarch); |
|
120 |
|
121 + if (regnum >= gdbarch_num_regs (gdbarch)) |
|
122 + return sparc32_pseudo_register_type (gdbarch, regnum); |
|
123 + |
|
124 return builtin_type (gdbarch)->builtin_int32; |
|
125 } |
|
126 |
|
127 @@ -431,6 +459,7 @@ |
|
128 { |
|
129 enum register_status status; |
|
130 |
|
131 + regnum -= gdbarch_num_regs (gdbarch); |
|
132 gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM); |
|
133 |
|
134 regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM); |
|
135 @@ -445,6 +474,7 @@ |
|
136 struct regcache *regcache, |
|
137 int regnum, const gdb_byte *buf) |
|
138 { |
|
139 + regnum -= gdbarch_num_regs (gdbarch); |
|
140 gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM); |
|
141 |
|
142 regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM); |
|
143 @@ -1660,11 +1690,36 @@ |
|
144 } |
|
145 |
|
146 |
|
147 +static int |
|
148 +validate_tdesc_registers (const struct target_desc *tdesc, |
|
149 + struct tdesc_arch_data *tdesc_data, |
|
150 + const char *feature_name, |
|
151 + const char *register_names[], |
|
152 + unsigned int registers_num, |
|
153 + unsigned int reg_start) |
|
154 +{ |
|
155 + int valid_p = 1; |
|
156 + const struct tdesc_feature *feature; |
|
157 + |
|
158 + feature = tdesc_find_feature (tdesc, feature_name); |
|
159 + if (feature == NULL) |
|
160 + return 0; |
|
161 + |
|
162 + for (unsigned int i = 0; i < registers_num; i++) |
|
163 + valid_p &= tdesc_numbered_register (feature, tdesc_data, |
|
164 + reg_start + i, |
|
165 + register_names[i]); |
|
166 + |
|
167 + return valid_p; |
|
168 +} |
|
169 + |
|
170 static struct gdbarch * |
|
171 sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) |
|
172 { |
|
173 struct gdbarch_tdep *tdep; |
|
174 + const struct target_desc *tdesc = info.target_desc; |
|
175 struct gdbarch *gdbarch; |
|
176 + int valid_p = 1; |
|
177 |
|
178 /* If there is already a candidate, use it. */ |
|
179 arches = gdbarch_list_lookup_by_info (arches, &info); |
|
180 @@ -1678,6 +1733,10 @@ |
|
181 tdep->pc_regnum = SPARC32_PC_REGNUM; |
|
182 tdep->npc_regnum = SPARC32_NPC_REGNUM; |
|
183 tdep->step_trap = sparc_step_trap; |
|
184 + tdep->fpu_register_names = sparc32_fpu_register_names; |
|
185 + tdep->fpu_registers_num = ARRAY_SIZE (sparc32_fpu_register_names); |
|
186 + tdep->cp0_register_names = sparc32_cp0_register_names; |
|
187 + tdep->cp0_registers_num = ARRAY_SIZE (sparc32_cp0_register_names); |
|
188 |
|
189 set_gdbarch_long_double_bit (gdbarch, 128); |
|
190 set_gdbarch_long_double_format (gdbarch, floatformats_sparc_quad); |
|
191 @@ -1686,6 +1745,8 @@ |
|
192 set_gdbarch_register_name (gdbarch, sparc32_register_name); |
|
193 set_gdbarch_register_type (gdbarch, sparc32_register_type); |
|
194 set_gdbarch_num_pseudo_regs (gdbarch, SPARC32_NUM_PSEUDO_REGS); |
|
195 + set_tdesc_pseudo_register_name (gdbarch, sparc32_pseudo_register_name); |
|
196 + set_tdesc_pseudo_register_type (gdbarch, sparc32_pseudo_register_type); |
|
197 set_gdbarch_pseudo_register_read (gdbarch, sparc32_pseudo_register_read); |
|
198 set_gdbarch_pseudo_register_write (gdbarch, sparc32_pseudo_register_write); |
|
199 |
|
200 @@ -1734,6 +1795,39 @@ |
|
201 |
|
202 frame_unwind_append_unwinder (gdbarch, &sparc32_frame_unwind); |
|
203 |
|
204 + if (tdesc_has_registers (tdesc)) |
|
205 + { |
|
206 + struct tdesc_arch_data *tdesc_data = tdesc_data_alloc (); |
|
207 + |
|
208 + /* Validate that the descriptor provides the mandatory registers |
|
209 + and allocate their numbers. */ |
|
210 + valid_p &= validate_tdesc_registers (tdesc, tdesc_data, |
|
211 + "org.gnu.gdb.sparc.cpu", |
|
212 + sparc_core_register_names, |
|
213 + ARRAY_SIZE (sparc_core_register_names), |
|
214 + SPARC_G0_REGNUM); |
|
215 + valid_p &= validate_tdesc_registers (tdesc, tdesc_data, |
|
216 + "org.gnu.gdb.sparc.fpu", |
|
217 + tdep->fpu_register_names, |
|
218 + tdep->fpu_registers_num, |
|
219 + SPARC_F0_REGNUM); |
|
220 + valid_p &= validate_tdesc_registers (tdesc, tdesc_data, |
|
221 + "org.gnu.gdb.sparc.cp0", |
|
222 + tdep->cp0_register_names, |
|
223 + tdep->cp0_registers_num, |
|
224 + SPARC_F0_REGNUM + |
|
225 + tdep->fpu_registers_num); |
|
226 + if (!valid_p) |
|
227 + { |
|
228 + tdesc_data_cleanup (tdesc_data); |
|
229 + return NULL; |
|
230 + } |
|
231 + |
|
232 + /* Target description may have changed. */ |
|
233 + info.tdep_info = tdesc_data; |
|
234 + tdesc_use_registers (gdbarch, tdesc, tdesc_data); |
|
235 + } |
|
236 + |
|
237 /* If we have register sets, enable the generic core file support. */ |
|
238 if (tdep->gregset) |
|
239 set_gdbarch_iterate_over_regset_sections |