xstormy16-tdep.c revision 1.11 1 1.1 christos /* Target-dependent code for the Sanyo Xstormy16a (LC590000) processor.
2 1.1 christos
3 1.11 christos Copyright (C) 2001-2024 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.11 christos #include "extract-store-integer.h"
21 1.1 christos #include "frame.h"
22 1.1 christos #include "frame-base.h"
23 1.1 christos #include "frame-unwind.h"
24 1.9 christos #include "dwarf2/frame.h"
25 1.1 christos #include "symtab.h"
26 1.1 christos #include "gdbtypes.h"
27 1.11 christos #include "cli/cli-cmds.h"
28 1.1 christos #include "gdbcore.h"
29 1.1 christos #include "value.h"
30 1.1 christos #include "dis-asm.h"
31 1.1 christos #include "inferior.h"
32 1.1 christos #include "arch-utils.h"
33 1.1 christos #include "regcache.h"
34 1.1 christos #include "osabi.h"
35 1.1 christos #include "objfiles.h"
36 1.9 christos #include "gdbsupport/byte-vector.h"
37 1.1 christos
38 1.1 christos enum gdb_regnum
39 1.1 christos {
40 1.1 christos /* Xstormy16 has 16 general purpose registers (R0-R15) plus PC.
41 1.1 christos Functions will return their values in register R2-R7 as they fit.
42 1.1 christos Otherwise a hidden pointer to an big enough area is given as argument
43 1.1 christos to the function in r2. Further arguments are beginning in r3 then.
44 1.1 christos R13 is used as frame pointer when GCC compiles w/o optimization
45 1.1 christos R14 is used as "PSW", displaying the CPU status.
46 1.9 christos R15 is used implicitly as stack pointer. */
47 1.1 christos E_R0_REGNUM,
48 1.1 christos E_R1_REGNUM,
49 1.1 christos E_R2_REGNUM, E_1ST_ARG_REGNUM = E_R2_REGNUM, E_PTR_RET_REGNUM = E_R2_REGNUM,
50 1.1 christos E_R3_REGNUM,
51 1.1 christos E_R4_REGNUM,
52 1.1 christos E_R5_REGNUM,
53 1.1 christos E_R6_REGNUM,
54 1.1 christos E_R7_REGNUM, E_LST_ARG_REGNUM = E_R7_REGNUM,
55 1.1 christos E_R8_REGNUM,
56 1.1 christos E_R9_REGNUM,
57 1.1 christos E_R10_REGNUM,
58 1.1 christos E_R11_REGNUM,
59 1.1 christos E_R12_REGNUM,
60 1.1 christos E_R13_REGNUM, E_FP_REGNUM = E_R13_REGNUM,
61 1.1 christos E_R14_REGNUM, E_PSW_REGNUM = E_R14_REGNUM,
62 1.1 christos E_R15_REGNUM, E_SP_REGNUM = E_R15_REGNUM,
63 1.1 christos E_PC_REGNUM,
64 1.1 christos E_NUM_REGS
65 1.1 christos };
66 1.1 christos
67 1.1 christos /* Use an invalid address value as 'not available' marker. */
68 1.1 christos enum { REG_UNAVAIL = (CORE_ADDR) -1 };
69 1.1 christos
70 1.1 christos struct xstormy16_frame_cache
71 1.1 christos {
72 1.1 christos /* Base address. */
73 1.1 christos CORE_ADDR base;
74 1.1 christos CORE_ADDR pc;
75 1.1 christos LONGEST framesize;
76 1.1 christos int uses_fp;
77 1.1 christos CORE_ADDR saved_regs[E_NUM_REGS];
78 1.1 christos CORE_ADDR saved_sp;
79 1.1 christos };
80 1.1 christos
81 1.1 christos /* Size of instructions, registers, etc. */
82 1.1 christos enum
83 1.1 christos {
84 1.1 christos xstormy16_inst_size = 2,
85 1.1 christos xstormy16_reg_size = 2,
86 1.1 christos xstormy16_pc_size = 4
87 1.1 christos };
88 1.1 christos
89 1.1 christos /* Size of return datatype which fits into the remaining return registers. */
90 1.1 christos #define E_MAX_RETTYPE_SIZE(regnum) ((E_LST_ARG_REGNUM - (regnum) + 1) \
91 1.1 christos * xstormy16_reg_size)
92 1.1 christos
93 1.1 christos /* Size of return datatype which fits into all return registers. */
94 1.1 christos enum
95 1.1 christos {
96 1.1 christos E_MAX_RETTYPE_SIZE_IN_REGS = E_MAX_RETTYPE_SIZE (E_R2_REGNUM)
97 1.1 christos };
98 1.1 christos
99 1.1 christos /* Function: xstormy16_register_name
100 1.1 christos Returns the name of the standard Xstormy16 register N. */
101 1.1 christos
102 1.1 christos static const char *
103 1.1 christos xstormy16_register_name (struct gdbarch *gdbarch, int regnum)
104 1.1 christos {
105 1.7 christos static const char *register_names[] = {
106 1.1 christos "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
107 1.1 christos "r8", "r9", "r10", "r11", "r12", "r13",
108 1.1 christos "psw", "sp", "pc"
109 1.1 christos };
110 1.1 christos
111 1.11 christos static_assert (ARRAY_SIZE (register_names) == E_NUM_REGS);
112 1.10 christos return register_names[regnum];
113 1.1 christos }
114 1.1 christos
115 1.1 christos static struct type *
116 1.1 christos xstormy16_register_type (struct gdbarch *gdbarch, int regnum)
117 1.1 christos {
118 1.1 christos if (regnum == E_PC_REGNUM)
119 1.1 christos return builtin_type (gdbarch)->builtin_uint32;
120 1.1 christos else
121 1.1 christos return builtin_type (gdbarch)->builtin_uint16;
122 1.1 christos }
123 1.1 christos
124 1.1 christos /* Function: xstormy16_type_is_scalar
125 1.1 christos Makes the decision if a given type is a scalar types. Scalar
126 1.1 christos types are returned in the registers r2-r7 as they fit. */
127 1.1 christos
128 1.1 christos static int
129 1.1 christos xstormy16_type_is_scalar (struct type *t)
130 1.1 christos {
131 1.9 christos return (t->code () != TYPE_CODE_STRUCT
132 1.9 christos && t->code () != TYPE_CODE_UNION
133 1.9 christos && t->code () != TYPE_CODE_ARRAY);
134 1.1 christos }
135 1.1 christos
136 1.1 christos /* Function: xstormy16_use_struct_convention
137 1.1 christos Returns non-zero if the given struct type will be returned using
138 1.1 christos a special convention, rather than the normal function return method.
139 1.1 christos 7sed in the contexts of the "return" command, and of
140 1.1 christos target function calls from the debugger. */
141 1.1 christos
142 1.1 christos static int
143 1.1 christos xstormy16_use_struct_convention (struct type *type)
144 1.1 christos {
145 1.1 christos return !xstormy16_type_is_scalar (type)
146 1.10 christos || type->length () > E_MAX_RETTYPE_SIZE_IN_REGS;
147 1.1 christos }
148 1.1 christos
149 1.1 christos /* Function: xstormy16_extract_return_value
150 1.1 christos Find a function's return value in the appropriate registers (in
151 1.1 christos regbuf), and copy it into valbuf. */
152 1.1 christos
153 1.1 christos static void
154 1.1 christos xstormy16_extract_return_value (struct type *type, struct regcache *regcache,
155 1.1 christos gdb_byte *valbuf)
156 1.1 christos {
157 1.10 christos int len = type->length ();
158 1.1 christos int i, regnum = E_1ST_ARG_REGNUM;
159 1.1 christos
160 1.1 christos for (i = 0; i < len; i += xstormy16_reg_size)
161 1.8 christos regcache->raw_read (regnum++, valbuf + i);
162 1.1 christos }
163 1.1 christos
164 1.1 christos /* Function: xstormy16_store_return_value
165 1.1 christos Copy the function return value from VALBUF into the
166 1.1 christos proper location for a function return.
167 1.1 christos Called only in the context of the "return" command. */
168 1.1 christos
169 1.1 christos static void
170 1.1 christos xstormy16_store_return_value (struct type *type, struct regcache *regcache,
171 1.1 christos const gdb_byte *valbuf)
172 1.1 christos {
173 1.10 christos if (type->length () == 1)
174 1.1 christos {
175 1.1 christos /* Add leading zeros to the value. */
176 1.1 christos gdb_byte buf[xstormy16_reg_size];
177 1.1 christos memset (buf, 0, xstormy16_reg_size);
178 1.1 christos memcpy (buf, valbuf, 1);
179 1.8 christos regcache->raw_write (E_1ST_ARG_REGNUM, buf);
180 1.1 christos }
181 1.1 christos else
182 1.1 christos {
183 1.10 christos int len = type->length ();
184 1.1 christos int i, regnum = E_1ST_ARG_REGNUM;
185 1.1 christos
186 1.1 christos for (i = 0; i < len; i += xstormy16_reg_size)
187 1.10 christos regcache->raw_write (regnum++, valbuf + i);
188 1.1 christos }
189 1.1 christos }
190 1.1 christos
191 1.1 christos static enum return_value_convention
192 1.1 christos xstormy16_return_value (struct gdbarch *gdbarch, struct value *function,
193 1.1 christos struct type *type, struct regcache *regcache,
194 1.1 christos gdb_byte *readbuf, const gdb_byte *writebuf)
195 1.1 christos {
196 1.1 christos if (xstormy16_use_struct_convention (type))
197 1.1 christos return RETURN_VALUE_STRUCT_CONVENTION;
198 1.1 christos if (writebuf)
199 1.1 christos xstormy16_store_return_value (type, regcache, writebuf);
200 1.1 christos else if (readbuf)
201 1.1 christos xstormy16_extract_return_value (type, regcache, readbuf);
202 1.1 christos return RETURN_VALUE_REGISTER_CONVENTION;
203 1.1 christos }
204 1.1 christos
205 1.1 christos static CORE_ADDR
206 1.1 christos xstormy16_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
207 1.1 christos {
208 1.1 christos if (addr & 1)
209 1.1 christos ++addr;
210 1.1 christos return addr;
211 1.1 christos }
212 1.1 christos
213 1.1 christos /* Function: xstormy16_push_dummy_call
214 1.1 christos Setup the function arguments for GDB to call a function in the inferior.
215 1.1 christos Called only in the context of a target function call from the debugger.
216 1.1 christos Returns the value of the SP register after the args are pushed. */
217 1.1 christos
218 1.1 christos static CORE_ADDR
219 1.1 christos xstormy16_push_dummy_call (struct gdbarch *gdbarch,
220 1.1 christos struct value *function,
221 1.1 christos struct regcache *regcache,
222 1.1 christos CORE_ADDR bp_addr, int nargs,
223 1.1 christos struct value **args,
224 1.8 christos CORE_ADDR sp,
225 1.8 christos function_call_return_method return_method,
226 1.1 christos CORE_ADDR struct_addr)
227 1.1 christos {
228 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
229 1.1 christos CORE_ADDR stack_dest = sp;
230 1.1 christos int argreg = E_1ST_ARG_REGNUM;
231 1.1 christos int i, j;
232 1.1 christos int typelen, slacklen;
233 1.1 christos gdb_byte buf[xstormy16_pc_size];
234 1.1 christos
235 1.8 christos /* If returning a struct using target ABI method, then the struct return
236 1.8 christos address will consume one argument-passing register. */
237 1.8 christos if (return_method == return_method_struct)
238 1.1 christos {
239 1.1 christos regcache_cooked_write_unsigned (regcache, E_PTR_RET_REGNUM, struct_addr);
240 1.1 christos argreg++;
241 1.1 christos }
242 1.1 christos
243 1.1 christos /* Arguments are passed in R2-R7 as they fit. If an argument doesn't
244 1.1 christos fit in the remaining registers we're switching over to the stack.
245 1.1 christos No argument is put on stack partially and as soon as we switched
246 1.1 christos over to stack no further argument is put in a register even if it
247 1.1 christos would fit in the remaining unused registers. */
248 1.1 christos for (i = 0; i < nargs && argreg <= E_LST_ARG_REGNUM; i++)
249 1.1 christos {
250 1.11 christos typelen = args[i]->enclosing_type ()->length ();
251 1.1 christos if (typelen > E_MAX_RETTYPE_SIZE (argreg))
252 1.1 christos break;
253 1.1 christos
254 1.1 christos /* Put argument into registers wordwise. */
255 1.11 christos const gdb_byte *val = args[i]->contents ().data ();
256 1.1 christos for (j = 0; j < typelen; j += xstormy16_reg_size)
257 1.1 christos {
258 1.1 christos ULONGEST regval;
259 1.1 christos int size = (typelen - j == 1) ? 1 : xstormy16_reg_size;
260 1.1 christos
261 1.1 christos regval = extract_unsigned_integer (val + j, size, byte_order);
262 1.1 christos regcache_cooked_write_unsigned (regcache, argreg++, regval);
263 1.1 christos }
264 1.1 christos }
265 1.1 christos
266 1.1 christos /* Align SP */
267 1.1 christos stack_dest = xstormy16_frame_align (gdbarch, stack_dest);
268 1.1 christos
269 1.1 christos /* Loop backwards through remaining arguments and push them on the stack,
270 1.1 christos wordaligned. */
271 1.1 christos for (j = nargs - 1; j >= i; j--)
272 1.1 christos {
273 1.11 christos const gdb_byte *bytes = args[j]->contents ().data ();
274 1.1 christos
275 1.11 christos typelen = args[j]->enclosing_type ()->length ();
276 1.1 christos slacklen = typelen & 1;
277 1.8 christos gdb::byte_vector val (typelen + slacklen);
278 1.8 christos memcpy (val.data (), bytes, typelen);
279 1.8 christos memset (val.data () + typelen, 0, slacklen);
280 1.1 christos
281 1.1 christos /* Now write this data to the stack. The stack grows upwards. */
282 1.8 christos write_memory (stack_dest, val.data (), typelen + slacklen);
283 1.1 christos stack_dest += typelen + slacklen;
284 1.1 christos }
285 1.1 christos
286 1.1 christos store_unsigned_integer (buf, xstormy16_pc_size, byte_order, bp_addr);
287 1.1 christos write_memory (stack_dest, buf, xstormy16_pc_size);
288 1.1 christos stack_dest += xstormy16_pc_size;
289 1.1 christos
290 1.1 christos /* Update stack pointer. */
291 1.1 christos regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, stack_dest);
292 1.1 christos
293 1.1 christos /* Return the new stack pointer minus the return address slot since
294 1.1 christos that's what DWARF2/GCC uses as the frame's CFA. */
295 1.1 christos return stack_dest - xstormy16_pc_size;
296 1.1 christos }
297 1.1 christos
298 1.1 christos /* Function: xstormy16_scan_prologue
299 1.1 christos Decode the instructions within the given address range.
300 1.1 christos Decide when we must have reached the end of the function prologue.
301 1.1 christos If a frame_info pointer is provided, fill in its saved_regs etc.
302 1.1 christos
303 1.1 christos Returns the address of the first instruction after the prologue. */
304 1.1 christos
305 1.1 christos static CORE_ADDR
306 1.1 christos xstormy16_analyze_prologue (struct gdbarch *gdbarch,
307 1.1 christos CORE_ADDR start_addr, CORE_ADDR end_addr,
308 1.1 christos struct xstormy16_frame_cache *cache,
309 1.11 christos const frame_info_ptr &this_frame)
310 1.1 christos {
311 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
312 1.1 christos CORE_ADDR next_addr;
313 1.1 christos ULONGEST inst, inst2;
314 1.1 christos LONGEST offset;
315 1.1 christos int regnum;
316 1.1 christos
317 1.1 christos /* Initialize framesize with size of PC put on stack by CALLF inst. */
318 1.1 christos cache->saved_regs[E_PC_REGNUM] = 0;
319 1.1 christos cache->framesize = xstormy16_pc_size;
320 1.1 christos
321 1.1 christos if (start_addr >= end_addr)
322 1.1 christos return end_addr;
323 1.1 christos
324 1.1 christos for (next_addr = start_addr;
325 1.1 christos next_addr < end_addr; next_addr += xstormy16_inst_size)
326 1.1 christos {
327 1.1 christos inst = read_memory_unsigned_integer (next_addr,
328 1.1 christos xstormy16_inst_size, byte_order);
329 1.1 christos inst2 = read_memory_unsigned_integer (next_addr + xstormy16_inst_size,
330 1.1 christos xstormy16_inst_size, byte_order);
331 1.1 christos
332 1.1 christos if (inst >= 0x0082 && inst <= 0x008d) /* push r2 .. push r13 */
333 1.1 christos {
334 1.1 christos regnum = inst & 0x000f;
335 1.1 christos cache->saved_regs[regnum] = cache->framesize;
336 1.1 christos cache->framesize += xstormy16_reg_size;
337 1.1 christos }
338 1.1 christos
339 1.1 christos /* Optional stack allocation for args and local vars <= 4 byte. */
340 1.1 christos else if (inst == 0x301f || inst == 0x303f) /* inc r15, #0x1/#0x3 */
341 1.1 christos {
342 1.1 christos cache->framesize += ((inst & 0x0030) >> 4) + 1;
343 1.1 christos }
344 1.1 christos
345 1.1 christos /* optional stack allocation for args and local vars > 4 && < 16 byte */
346 1.1 christos else if ((inst & 0xff0f) == 0x510f) /* 51Hf add r15, #0xH */
347 1.1 christos {
348 1.1 christos cache->framesize += (inst & 0x00f0) >> 4;
349 1.1 christos }
350 1.1 christos
351 1.1 christos /* Optional stack allocation for args and local vars >= 16 byte. */
352 1.1 christos else if (inst == 0x314f && inst2 >= 0x0010) /* 314f HHHH add r15, #0xH */
353 1.1 christos {
354 1.1 christos cache->framesize += inst2;
355 1.1 christos next_addr += xstormy16_inst_size;
356 1.1 christos }
357 1.1 christos
358 1.1 christos else if (inst == 0x46fd) /* mov r13, r15 */
359 1.1 christos {
360 1.1 christos cache->uses_fp = 1;
361 1.1 christos }
362 1.1 christos
363 1.1 christos /* optional copying of args in r2-r7 to r10-r13. */
364 1.1 christos /* Probably only in optimized case but legal action for prologue. */
365 1.1 christos else if ((inst & 0xff00) == 0x4600 /* 46SD mov rD, rS */
366 1.1 christos && (inst & 0x00f0) >= 0x0020 && (inst & 0x00f0) <= 0x0070
367 1.3 christos && (inst & 0x000f) >= 0x000a && (inst & 0x000f) <= 0x000d)
368 1.1 christos ;
369 1.1 christos
370 1.1 christos /* Optional copying of args in r2-r7 to stack. */
371 1.1 christos /* 72DS HHHH mov.b (rD, 0xHHHH), r(S-8)
372 1.1 christos (bit3 always 1, bit2-0 = reg) */
373 1.1 christos /* 73DS HHHH mov.w (rD, 0xHHHH), r(S-8) */
374 1.1 christos else if ((inst & 0xfed8) == 0x72d8 && (inst & 0x0007) >= 2)
375 1.1 christos {
376 1.1 christos regnum = inst & 0x0007;
377 1.1 christos /* Only 12 of 16 bits of the argument are used for the
378 1.1 christos signed offset. */
379 1.1 christos offset = (LONGEST) (inst2 & 0x0fff);
380 1.1 christos if (offset & 0x0800)
381 1.1 christos offset -= 0x1000;
382 1.1 christos
383 1.1 christos cache->saved_regs[regnum] = cache->framesize + offset;
384 1.1 christos next_addr += xstormy16_inst_size;
385 1.1 christos }
386 1.1 christos
387 1.1 christos else /* Not a prologue instruction. */
388 1.1 christos break;
389 1.1 christos }
390 1.1 christos
391 1.1 christos return next_addr;
392 1.1 christos }
393 1.1 christos
394 1.1 christos /* Function: xstormy16_skip_prologue
395 1.1 christos If the input address is in a function prologue,
396 1.1 christos returns the address of the end of the prologue;
397 1.1 christos else returns the input address.
398 1.1 christos
399 1.1 christos Note: the input address is likely to be the function start,
400 1.1 christos since this function is mainly used for advancing a breakpoint
401 1.1 christos to the first line, or stepping to the first line when we have
402 1.1 christos stepped into a function call. */
403 1.1 christos
404 1.1 christos static CORE_ADDR
405 1.1 christos xstormy16_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
406 1.1 christos {
407 1.1 christos CORE_ADDR func_addr = 0, func_end = 0;
408 1.1 christos const char *func_name;
409 1.1 christos
410 1.1 christos if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
411 1.1 christos {
412 1.1 christos struct symtab_and_line sal;
413 1.1 christos struct symbol *sym;
414 1.1 christos struct xstormy16_frame_cache cache;
415 1.1 christos CORE_ADDR plg_end;
416 1.1 christos
417 1.1 christos memset (&cache, 0, sizeof cache);
418 1.1 christos
419 1.1 christos /* Don't trust line number debug info in frameless functions. */
420 1.1 christos plg_end = xstormy16_analyze_prologue (gdbarch, func_addr, func_end,
421 1.1 christos &cache, NULL);
422 1.1 christos if (!cache.uses_fp)
423 1.10 christos return plg_end;
424 1.1 christos
425 1.1 christos /* Found a function. */
426 1.11 christos sym = lookup_symbol (func_name, NULL, SEARCH_FUNCTION_DOMAIN,
427 1.11 christos nullptr).symbol;
428 1.1 christos /* Don't use line number debug info for assembly source files. */
429 1.9 christos if (sym && sym->language () != language_asm)
430 1.1 christos {
431 1.1 christos sal = find_pc_line (func_addr, 0);
432 1.1 christos if (sal.end && sal.end < func_end)
433 1.1 christos {
434 1.1 christos /* Found a line number, use it as end of prologue. */
435 1.1 christos return sal.end;
436 1.1 christos }
437 1.1 christos }
438 1.1 christos /* No useable line symbol. Use result of prologue parsing method. */
439 1.1 christos return plg_end;
440 1.1 christos }
441 1.1 christos
442 1.1 christos /* No function symbol -- just return the PC. */
443 1.1 christos
444 1.1 christos return (CORE_ADDR) pc;
445 1.1 christos }
446 1.1 christos
447 1.5 christos /* Implement the stack_frame_destroyed_p gdbarch method.
448 1.5 christos
449 1.5 christos The epilogue is defined here as the area at the end of a function,
450 1.1 christos either on the `ret' instruction itself or after an instruction which
451 1.1 christos destroys the function's stack frame. */
452 1.5 christos
453 1.1 christos static int
454 1.5 christos xstormy16_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
455 1.1 christos {
456 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
457 1.1 christos CORE_ADDR func_addr = 0, func_end = 0;
458 1.1 christos
459 1.1 christos if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
460 1.1 christos {
461 1.1 christos ULONGEST inst, inst2;
462 1.1 christos CORE_ADDR addr = func_end - xstormy16_inst_size;
463 1.1 christos
464 1.1 christos /* The Xstormy16 epilogue is max. 14 bytes long. */
465 1.1 christos if (pc < func_end - 7 * xstormy16_inst_size)
466 1.1 christos return 0;
467 1.1 christos
468 1.1 christos /* Check if we're on a `ret' instruction. Otherwise it's
469 1.10 christos too dangerous to proceed. */
470 1.1 christos inst = read_memory_unsigned_integer (addr,
471 1.1 christos xstormy16_inst_size, byte_order);
472 1.1 christos if (inst != 0x0003)
473 1.1 christos return 0;
474 1.1 christos
475 1.1 christos while ((addr -= xstormy16_inst_size) >= func_addr)
476 1.1 christos {
477 1.1 christos inst = read_memory_unsigned_integer (addr,
478 1.1 christos xstormy16_inst_size,
479 1.1 christos byte_order);
480 1.1 christos if (inst >= 0x009a && inst <= 0x009d) /* pop r10...r13 */
481 1.1 christos continue;
482 1.1 christos if (inst == 0x305f || inst == 0x307f) /* dec r15, #0x1/#0x3 */
483 1.1 christos break;
484 1.1 christos inst2 = read_memory_unsigned_integer (addr - xstormy16_inst_size,
485 1.1 christos xstormy16_inst_size,
486 1.1 christos byte_order);
487 1.1 christos if (inst2 == 0x314f && inst >= 0x8000) /* add r15, neg. value */
488 1.1 christos {
489 1.1 christos addr -= xstormy16_inst_size;
490 1.1 christos break;
491 1.1 christos }
492 1.1 christos return 0;
493 1.1 christos }
494 1.1 christos if (pc > addr)
495 1.1 christos return 1;
496 1.1 christos }
497 1.1 christos return 0;
498 1.1 christos }
499 1.1 christos
500 1.7 christos constexpr gdb_byte xstormy16_break_insn[] = { 0x06, 0x0 };
501 1.7 christos
502 1.7 christos typedef BP_MANIPULATION (xstormy16_break_insn) xstormy16_breakpoint;
503 1.1 christos
504 1.1 christos /* Given a pointer to a jump table entry, return the address
505 1.1 christos of the function it jumps to. Return 0 if not found. */
506 1.1 christos static CORE_ADDR
507 1.1 christos xstormy16_resolve_jmp_table_entry (struct gdbarch *gdbarch, CORE_ADDR faddr)
508 1.1 christos {
509 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
510 1.1 christos struct obj_section *faddr_sect = find_pc_section (faddr);
511 1.1 christos
512 1.1 christos if (faddr_sect)
513 1.1 christos {
514 1.1 christos LONGEST inst, inst2, addr;
515 1.1 christos gdb_byte buf[2 * xstormy16_inst_size];
516 1.1 christos
517 1.1 christos /* Return faddr if it's not pointing into the jump table. */
518 1.1 christos if (strcmp (faddr_sect->the_bfd_section->name, ".plt"))
519 1.1 christos return faddr;
520 1.1 christos
521 1.1 christos if (!target_read_memory (faddr, buf, sizeof buf))
522 1.1 christos {
523 1.1 christos inst = extract_unsigned_integer (buf,
524 1.1 christos xstormy16_inst_size, byte_order);
525 1.1 christos inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
526 1.1 christos xstormy16_inst_size, byte_order);
527 1.1 christos addr = inst2 << 8 | (inst & 0xff);
528 1.1 christos return addr;
529 1.1 christos }
530 1.1 christos }
531 1.1 christos return 0;
532 1.1 christos }
533 1.1 christos
534 1.1 christos /* Given a function's address, attempt to find (and return) the
535 1.1 christos address of the corresponding jump table entry. Return 0 if
536 1.1 christos not found. */
537 1.1 christos static CORE_ADDR
538 1.1 christos xstormy16_find_jmp_table_entry (struct gdbarch *gdbarch, CORE_ADDR faddr)
539 1.1 christos {
540 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
541 1.1 christos struct obj_section *faddr_sect = find_pc_section (faddr);
542 1.1 christos
543 1.1 christos if (faddr_sect)
544 1.1 christos {
545 1.1 christos /* Return faddr if it's already a pointer to a jump table entry. */
546 1.1 christos if (!strcmp (faddr_sect->the_bfd_section->name, ".plt"))
547 1.1 christos return faddr;
548 1.1 christos
549 1.11 christos for (obj_section *osect : faddr_sect->objfile->sections ())
550 1.1 christos {
551 1.11 christos if (!strcmp (osect->the_bfd_section->name, ".plt"))
552 1.11 christos {
553 1.11 christos CORE_ADDR addr, endaddr;
554 1.1 christos
555 1.11 christos addr = osect->addr ();
556 1.11 christos endaddr = osect->endaddr ();
557 1.1 christos
558 1.11 christos for (; addr < endaddr; addr += 2 * xstormy16_inst_size)
559 1.11 christos {
560 1.11 christos LONGEST inst, inst2, faddr2;
561 1.11 christos gdb_byte buf[2 * xstormy16_inst_size];
562 1.11 christos
563 1.11 christos if (target_read_memory (addr, buf, sizeof buf))
564 1.11 christos return 0;
565 1.11 christos inst = extract_unsigned_integer (buf,
566 1.11 christos xstormy16_inst_size,
567 1.11 christos byte_order);
568 1.11 christos inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
569 1.11 christos xstormy16_inst_size,
570 1.11 christos byte_order);
571 1.11 christos faddr2 = inst2 << 8 | (inst & 0xff);
572 1.11 christos if (faddr == faddr2)
573 1.11 christos return addr;
574 1.11 christos }
575 1.1 christos
576 1.11 christos break;
577 1.1 christos }
578 1.1 christos }
579 1.1 christos }
580 1.1 christos return 0;
581 1.1 christos }
582 1.1 christos
583 1.1 christos static CORE_ADDR
584 1.11 christos xstormy16_skip_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc)
585 1.1 christos {
586 1.1 christos struct gdbarch *gdbarch = get_frame_arch (frame);
587 1.1 christos CORE_ADDR tmp = xstormy16_resolve_jmp_table_entry (gdbarch, pc);
588 1.1 christos
589 1.1 christos if (tmp && tmp != pc)
590 1.1 christos return tmp;
591 1.1 christos return 0;
592 1.1 christos }
593 1.1 christos
594 1.1 christos /* Function pointers are 16 bit. The address space is 24 bit, using
595 1.1 christos 32 bit addresses. Pointers to functions on the XStormy16 are implemented
596 1.1 christos by using 16 bit pointers, which are either direct pointers in case the
597 1.1 christos function begins below 0x10000, or indirect pointers into a jump table.
598 1.1 christos The next two functions convert 16 bit pointers into 24 (32) bit addresses
599 1.1 christos and vice versa. */
600 1.1 christos
601 1.1 christos static CORE_ADDR
602 1.1 christos xstormy16_pointer_to_address (struct gdbarch *gdbarch,
603 1.1 christos struct type *type, const gdb_byte *buf)
604 1.1 christos {
605 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
606 1.10 christos enum type_code target = type->target_type ()->code ();
607 1.1 christos CORE_ADDR addr
608 1.10 christos = extract_unsigned_integer (buf, type->length (), byte_order);
609 1.1 christos
610 1.1 christos if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
611 1.1 christos {
612 1.1 christos CORE_ADDR addr2 = xstormy16_resolve_jmp_table_entry (gdbarch, addr);
613 1.1 christos if (addr2)
614 1.1 christos addr = addr2;
615 1.1 christos }
616 1.1 christos
617 1.1 christos return addr;
618 1.1 christos }
619 1.1 christos
620 1.1 christos static void
621 1.1 christos xstormy16_address_to_pointer (struct gdbarch *gdbarch,
622 1.1 christos struct type *type, gdb_byte *buf, CORE_ADDR addr)
623 1.1 christos {
624 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
625 1.10 christos enum type_code target = type->target_type ()->code ();
626 1.1 christos
627 1.1 christos if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
628 1.1 christos {
629 1.1 christos CORE_ADDR addr2 = xstormy16_find_jmp_table_entry (gdbarch, addr);
630 1.1 christos if (addr2)
631 1.1 christos addr = addr2;
632 1.1 christos }
633 1.10 christos store_unsigned_integer (buf, type->length (), byte_order, addr);
634 1.1 christos }
635 1.1 christos
636 1.1 christos static struct xstormy16_frame_cache *
637 1.1 christos xstormy16_alloc_frame_cache (void)
638 1.1 christos {
639 1.1 christos struct xstormy16_frame_cache *cache;
640 1.1 christos int i;
641 1.1 christos
642 1.1 christos cache = FRAME_OBSTACK_ZALLOC (struct xstormy16_frame_cache);
643 1.1 christos
644 1.1 christos cache->base = 0;
645 1.1 christos cache->saved_sp = 0;
646 1.1 christos cache->pc = 0;
647 1.1 christos cache->uses_fp = 0;
648 1.1 christos cache->framesize = 0;
649 1.1 christos for (i = 0; i < E_NUM_REGS; ++i)
650 1.1 christos cache->saved_regs[i] = REG_UNAVAIL;
651 1.1 christos
652 1.1 christos return cache;
653 1.1 christos }
654 1.1 christos
655 1.1 christos static struct xstormy16_frame_cache *
656 1.11 christos xstormy16_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
657 1.1 christos {
658 1.1 christos struct gdbarch *gdbarch = get_frame_arch (this_frame);
659 1.1 christos struct xstormy16_frame_cache *cache;
660 1.1 christos CORE_ADDR current_pc;
661 1.1 christos int i;
662 1.1 christos
663 1.1 christos if (*this_cache)
664 1.6 christos return (struct xstormy16_frame_cache *) *this_cache;
665 1.1 christos
666 1.1 christos cache = xstormy16_alloc_frame_cache ();
667 1.1 christos *this_cache = cache;
668 1.1 christos
669 1.1 christos cache->base = get_frame_register_unsigned (this_frame, E_FP_REGNUM);
670 1.1 christos if (cache->base == 0)
671 1.1 christos return cache;
672 1.1 christos
673 1.1 christos cache->pc = get_frame_func (this_frame);
674 1.1 christos current_pc = get_frame_pc (this_frame);
675 1.1 christos if (cache->pc)
676 1.1 christos xstormy16_analyze_prologue (gdbarch, cache->pc, current_pc,
677 1.1 christos cache, this_frame);
678 1.1 christos
679 1.1 christos if (!cache->uses_fp)
680 1.1 christos cache->base = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
681 1.1 christos
682 1.1 christos cache->saved_sp = cache->base - cache->framesize;
683 1.1 christos
684 1.1 christos for (i = 0; i < E_NUM_REGS; ++i)
685 1.1 christos if (cache->saved_regs[i] != REG_UNAVAIL)
686 1.1 christos cache->saved_regs[i] += cache->saved_sp;
687 1.1 christos
688 1.1 christos return cache;
689 1.1 christos }
690 1.1 christos
691 1.1 christos static struct value *
692 1.11 christos xstormy16_frame_prev_register (const frame_info_ptr &this_frame,
693 1.1 christos void **this_cache, int regnum)
694 1.1 christos {
695 1.1 christos struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
696 1.10 christos this_cache);
697 1.1 christos gdb_assert (regnum >= 0);
698 1.1 christos
699 1.1 christos if (regnum == E_SP_REGNUM && cache->saved_sp)
700 1.1 christos return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
701 1.1 christos
702 1.1 christos if (regnum < E_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
703 1.1 christos return frame_unwind_got_memory (this_frame, regnum,
704 1.1 christos cache->saved_regs[regnum]);
705 1.1 christos
706 1.1 christos return frame_unwind_got_register (this_frame, regnum, regnum);
707 1.1 christos }
708 1.1 christos
709 1.1 christos static void
710 1.11 christos xstormy16_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
711 1.1 christos struct frame_id *this_id)
712 1.1 christos {
713 1.1 christos struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
714 1.1 christos this_cache);
715 1.1 christos
716 1.1 christos /* This marks the outermost frame. */
717 1.1 christos if (cache->base == 0)
718 1.1 christos return;
719 1.1 christos
720 1.1 christos *this_id = frame_id_build (cache->saved_sp, cache->pc);
721 1.1 christos }
722 1.1 christos
723 1.1 christos static CORE_ADDR
724 1.11 christos xstormy16_frame_base_address (const frame_info_ptr &this_frame, void **this_cache)
725 1.1 christos {
726 1.1 christos struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
727 1.1 christos this_cache);
728 1.1 christos return cache->base;
729 1.1 christos }
730 1.1 christos
731 1.1 christos static const struct frame_unwind xstormy16_frame_unwind = {
732 1.10 christos "xstormy16 prologue",
733 1.1 christos NORMAL_FRAME,
734 1.1 christos default_frame_unwind_stop_reason,
735 1.1 christos xstormy16_frame_this_id,
736 1.1 christos xstormy16_frame_prev_register,
737 1.1 christos NULL,
738 1.1 christos default_frame_sniffer
739 1.1 christos };
740 1.1 christos
741 1.1 christos static const struct frame_base xstormy16_frame_base = {
742 1.1 christos &xstormy16_frame_unwind,
743 1.1 christos xstormy16_frame_base_address,
744 1.1 christos xstormy16_frame_base_address,
745 1.1 christos xstormy16_frame_base_address
746 1.1 christos };
747 1.1 christos
748 1.1 christos /* Function: xstormy16_gdbarch_init
749 1.1 christos Initializer function for the xstormy16 gdbarch vector.
750 1.1 christos Called by gdbarch. Sets up the gdbarch vector(s) for this target. */
751 1.1 christos
752 1.1 christos static struct gdbarch *
753 1.1 christos xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
754 1.1 christos {
755 1.1 christos struct gdbarch *gdbarch;
756 1.1 christos
757 1.1 christos /* find a candidate among the list of pre-declared architectures. */
758 1.1 christos arches = gdbarch_list_lookup_by_info (arches, &info);
759 1.1 christos if (arches != NULL)
760 1.1 christos return (arches->gdbarch);
761 1.1 christos
762 1.1 christos gdbarch = gdbarch_alloc (&info, NULL);
763 1.1 christos
764 1.1 christos /*
765 1.1 christos * Basic register fields and methods, datatype sizes and stuff.
766 1.1 christos */
767 1.1 christos
768 1.1 christos set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
769 1.1 christos set_gdbarch_num_pseudo_regs (gdbarch, 0);
770 1.1 christos set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
771 1.1 christos set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
772 1.1 christos set_gdbarch_register_name (gdbarch, xstormy16_register_name);
773 1.1 christos set_gdbarch_register_type (gdbarch, xstormy16_register_type);
774 1.1 christos
775 1.1 christos set_gdbarch_char_signed (gdbarch, 0);
776 1.1 christos set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
777 1.1 christos set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
778 1.1 christos set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
779 1.1 christos set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
780 1.1 christos
781 1.7 christos set_gdbarch_wchar_bit (gdbarch, 2 * TARGET_CHAR_BIT);
782 1.7 christos set_gdbarch_wchar_signed (gdbarch, 1);
783 1.7 christos
784 1.1 christos set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
785 1.1 christos set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
786 1.1 christos set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
787 1.1 christos
788 1.1 christos set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
789 1.1 christos set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
790 1.1 christos set_gdbarch_dwarf2_addr_size (gdbarch, 4);
791 1.1 christos
792 1.1 christos set_gdbarch_address_to_pointer (gdbarch, xstormy16_address_to_pointer);
793 1.1 christos set_gdbarch_pointer_to_address (gdbarch, xstormy16_pointer_to_address);
794 1.1 christos
795 1.1 christos /* Stack grows up. */
796 1.1 christos set_gdbarch_inner_than (gdbarch, core_addr_greaterthan);
797 1.1 christos
798 1.1 christos /*
799 1.1 christos * Frame Info
800 1.1 christos */
801 1.1 christos set_gdbarch_frame_align (gdbarch, xstormy16_frame_align);
802 1.1 christos frame_base_set_default (gdbarch, &xstormy16_frame_base);
803 1.1 christos
804 1.1 christos set_gdbarch_skip_prologue (gdbarch, xstormy16_skip_prologue);
805 1.5 christos set_gdbarch_stack_frame_destroyed_p (gdbarch,
806 1.5 christos xstormy16_stack_frame_destroyed_p);
807 1.1 christos
808 1.1 christos /* These values and methods are used when gdb calls a target function. */
809 1.1 christos set_gdbarch_push_dummy_call (gdbarch, xstormy16_push_dummy_call);
810 1.7 christos set_gdbarch_breakpoint_kind_from_pc (gdbarch,
811 1.7 christos xstormy16_breakpoint::kind_from_pc);
812 1.7 christos set_gdbarch_sw_breakpoint_from_kind (gdbarch,
813 1.7 christos xstormy16_breakpoint::bp_from_kind);
814 1.1 christos set_gdbarch_return_value (gdbarch, xstormy16_return_value);
815 1.1 christos
816 1.1 christos set_gdbarch_skip_trampoline_code (gdbarch, xstormy16_skip_trampoline_code);
817 1.1 christos
818 1.1 christos gdbarch_init_osabi (info, gdbarch);
819 1.1 christos
820 1.1 christos dwarf2_append_unwinders (gdbarch);
821 1.1 christos frame_unwind_append_unwinder (gdbarch, &xstormy16_frame_unwind);
822 1.1 christos
823 1.1 christos return gdbarch;
824 1.1 christos }
825 1.1 christos
826 1.1 christos /* Function: _initialize_xstormy16_tdep
827 1.1 christos Initializer function for the Sanyo Xstormy16a module.
828 1.1 christos Called by gdb at start-up. */
829 1.1 christos
830 1.9 christos void _initialize_xstormy16_tdep ();
831 1.1 christos void
832 1.9 christos _initialize_xstormy16_tdep ()
833 1.1 christos {
834 1.10 christos gdbarch_register (bfd_arch_xstormy16, xstormy16_gdbarch_init);
835 1.1 christos }
836