]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/moxie-tdep.c
* defs.h (strlen_paddr, paddr, paddr_nz): Remove.
[thirdparty/binutils-gdb.git] / gdb / moxie-tdep.c
CommitLineData
d7066cce
AG
1/* Target-dependent code for Moxie.
2
3 Copyright (C) 2009 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include "defs.h"
21#include "frame.h"
22#include "frame-unwind.h"
23#include "frame-base.h"
24#include "symtab.h"
25#include "gdbtypes.h"
26#include "gdbcmd.h"
27#include "gdbcore.h"
28#include "gdb_string.h"
29#include "value.h"
30#include "inferior.h"
31#include "symfile.h"
32#include "objfiles.h"
33#include "osabi.h"
34#include "language.h"
35#include "arch-utils.h"
36#include "regcache.h"
37#include "trad-frame.h"
38#include "dis-asm.h"
39
40#include "gdb_assert.h"
41
42#include "moxie-tdep.h"
43
44/* Local functions. */
45
46extern void _initialize_moxie_tdep (void);
47
48/* Use an invalid address value as 'not available' marker. */
49enum { REG_UNAVAIL = (CORE_ADDR) -1 };
50
51struct moxie_frame_cache
52{
53 /* Base address. */
54 CORE_ADDR base;
55 CORE_ADDR pc;
56 LONGEST framesize;
57 CORE_ADDR saved_regs[MOXIE_NUM_REGS];
58 CORE_ADDR saved_sp;
59};
60
61/* Implement the "frame_align" gdbarch method. */
62
63static CORE_ADDR
64moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
65{
66 /* Align to the size of an instruction (so that they can safely be
67 pushed onto the stack. */
68 return sp & ~1;
69}
70
71/* Implement the "breakpoint_from_pc" gdbarch method. */
72
73const static unsigned char *
74moxie_breakpoint_from_pc (struct gdbarch *gdbarch,
75 CORE_ADDR *pcptr, int *lenptr)
76{
77 static unsigned char breakpoint[] = { 0x35, 0x00 };
78
79 *lenptr = sizeof (breakpoint);
80 return breakpoint;
81}
82
83/* Moxie register names. */
84
85char *moxie_register_names[] = {
86 "$fp", "$sp", "$r0", "$r1", "$r2",
87 "$r3", "$r4", "$r5", "$r6", "$r7",
88 "$r8", "$r9", "$r10", "$r11", "$r12",
89 "$r13", "$pc", "$cc" };
90
91/* Implement the "register_name" gdbarch method. */
92
93static const char *
94moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
95{
96 if (reg_nr < 0)
97 return NULL;
98 if (reg_nr >= MOXIE_NUM_REGS)
99 return NULL;
100 return moxie_register_names[reg_nr];
101}
102
103/* Implement the "register_type" gdbarch method. */
104
105static struct type *
106moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
107{
108 if (reg_nr == MOXIE_PC_REGNUM)
109 return builtin_type (gdbarch)->builtin_func_ptr;
110 else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
111 return builtin_type (gdbarch)->builtin_data_ptr;
112 else
df4df182 113 return builtin_type (gdbarch)->builtin_int32;
d7066cce
AG
114}
115
116/* Write into appropriate registers a function return value
117 of type TYPE, given in virtual format. */
118
119static void
120moxie_store_return_value (struct type *type, struct regcache *regcache,
121 const void *valbuf)
122{
123 CORE_ADDR regval;
124 int len = TYPE_LENGTH (type);
125
126 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
127 regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len);
128 regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
129 if (len > 4)
130 {
131 regval = extract_unsigned_integer ((gdb_byte *) valbuf + 4, len - 4);
132 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
133 }
134}
135
136/* Decode the instructions within the given address range. Decide
137 when we must have reached the end of the function prologue. If a
138 frame_info pointer is provided, fill in its saved_regs etc.
139
140 Returns the address of the first instruction after the prologue. */
141
142static CORE_ADDR
143moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
144 struct moxie_frame_cache *cache,
145 struct frame_info *this_frame)
146{
147 CORE_ADDR next_addr;
148 ULONGEST inst, inst2;
149 LONGEST offset;
150 int regnum;
151
152 /* Record where the jsra instruction saves the PC and FP. */
153 cache->saved_regs[MOXIE_PC_REGNUM] = -4;
154 cache->saved_regs[MOXIE_FP_REGNUM] = 0;
155 cache->framesize = 0;
156
157 if (start_addr >= end_addr)
158 return end_addr;
159
160 for (next_addr = start_addr; next_addr < end_addr; )
161 {
162 inst = read_memory_unsigned_integer (next_addr, 2);
163
164 /* Match "push $rN" where N is between 2 and 13 inclusive. */
165 if (inst >= 0x0614 && inst <= 0x061f)
166 {
167 regnum = inst & 0x000f;
168 cache->framesize += 4;
169 cache->saved_regs[regnum] = cache->framesize;
170 next_addr += 2;
171 }
172
173 /* Optional stack allocation for args and local vars <= 4
174 byte. */
175 else if (inst == 0x01f0) /* ldi.l $r12, X */
176 {
177 offset = read_memory_integer (next_addr + 2, 4);
178 inst2 = read_memory_unsigned_integer (next_addr + 6, 2);
179
180 if (inst2 == 0x051f) /* add.l $sp, $r12 */
181 {
182 cache->framesize += offset;
183 }
184
185 return (next_addr + 8);
186 }
187 else /* This is not a prologue instruction. */
188 break;
189 }
190
191 return next_addr;
192}
193
194/* Find the end of function prologue. */
195
196static CORE_ADDR
197moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
198{
199 CORE_ADDR func_addr = 0, func_end = 0;
200 char *func_name;
201
202 /* See if we can determine the end of the prologue via the symbol table.
203 If so, then return either PC, or the PC after the prologue, whichever
204 is greater. */
205 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
206 {
d80b854b
UW
207 CORE_ADDR post_prologue_pc
208 = skip_prologue_using_sal (gdbarch, func_addr);
d7066cce
AG
209 if (post_prologue_pc != 0)
210 return max (pc, post_prologue_pc);
211 else
212 {
213 /* Can't determine prologue from the symbol table, need to examine
214 instructions. */
215 struct symtab_and_line sal;
216 struct symbol *sym;
217 struct moxie_frame_cache cache;
218 CORE_ADDR plg_end;
219
220 memset (&cache, 0, sizeof cache);
221
222 plg_end = moxie_analyze_prologue (func_addr,
223 func_end, &cache, NULL);
224 /* Found a function. */
225 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
226 /* Don't use line number debug info for assembly source
227 files. */
228 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
229 {
230 sal = find_pc_line (func_addr, 0);
231 if (sal.end && sal.end < func_end)
232 {
233 /* Found a line number, use it as end of
234 prologue. */
235 return sal.end;
236 }
237 }
238 /* No useable line symbol. Use result of prologue parsing
239 method. */
240 return plg_end;
241 }
242 }
243
244 /* No function symbol -- just return the PC. */
245 return (CORE_ADDR) pc;
246}
247
248struct moxie_unwind_cache
249{
250 /* The previous frame's inner most stack address. Used as this
251 frame ID's stack_addr. */
252 CORE_ADDR prev_sp;
253 /* The frame's base, optionally used by the high-level debug info. */
254 CORE_ADDR base;
255 int size;
256 /* How far the SP and r13 (FP) have been offset from the start of
257 the stack frame (as defined by the previous frame's stack
258 pointer). */
259 LONGEST sp_offset;
260 LONGEST r13_offset;
261 int uses_frame;
262 /* Table indicating the location of each and every register. */
263 struct trad_frame_saved_reg *saved_regs;
264};
265
266/* Implement the "read_pc" gdbarch method. */
267
268static CORE_ADDR
269moxie_read_pc (struct regcache *regcache)
270{
271 ULONGEST pc;
272
273 regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
274 return pc;
275}
276
277/* Implement the "write_pc" gdbarch method. */
278
279static void
280moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
281{
282 regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
283}
284
285/* Implement the "unwind_pc" gdbarch method. */
286
287static CORE_ADDR
288moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
289{
290 return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
291}
292
293/* Given a return value in `regbuf' with a type `valtype',
294 extract and copy its value into `valbuf'. */
295
296static void
297moxie_extract_return_value (struct type *type, struct regcache *regcache,
298 void *dst)
299{
300 bfd_byte *valbuf = dst;
301 int len = TYPE_LENGTH (type);
302 ULONGEST tmp;
303
304 /* By using store_unsigned_integer we avoid having to do
305 anything special for small big-endian values. */
306 regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
307 store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), tmp);
308
309 /* Ignore return values more than 8 bytes in size because the moxie
310 returns anything more than 8 bytes in the stack. */
311 if (len > 4)
312 {
313 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
314 store_unsigned_integer (valbuf + len - 4, 4, tmp);
315 }
316}
317
318/* Implement the "return_value" gdbarch method. */
319
320static enum return_value_convention
321moxie_return_value (struct gdbarch *gdbarch, struct type *func_type,
322 struct type *valtype, struct regcache *regcache,
323 gdb_byte *readbuf, const gdb_byte *writebuf)
324{
325 if (TYPE_LENGTH (valtype) > 8)
326 return RETURN_VALUE_STRUCT_CONVENTION;
327 else
328 {
329 if (readbuf != NULL)
330 moxie_extract_return_value (valtype, regcache, readbuf);
331 if (writebuf != NULL)
332 moxie_store_return_value (valtype, regcache, writebuf);
333 return RETURN_VALUE_REGISTER_CONVENTION;
334 }
335}
336
337/* Allocate and initialize a moxie_frame_cache object. */
338
339static struct moxie_frame_cache *
340moxie_alloc_frame_cache (void)
341{
342 struct moxie_frame_cache *cache;
343 int i;
344
345 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
346
347 cache->base = 0;
348 cache->saved_sp = 0;
349 cache->pc = 0;
350 cache->framesize = 0;
351 for (i = 0; i < MOXIE_NUM_REGS; ++i)
352 cache->saved_regs[i] = REG_UNAVAIL;
353
354 return cache;
355}
356
357/* Populate a moxie_frame_cache object for this_frame. */
358
359static struct moxie_frame_cache *
360moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
361{
362 struct moxie_frame_cache *cache;
363 CORE_ADDR current_pc;
364 int i;
365
366 if (*this_cache)
367 return *this_cache;
368
369 cache = moxie_alloc_frame_cache ();
370 *this_cache = cache;
371
372 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
373 if (cache->base == 0)
374 return cache;
375
376 cache->pc = get_frame_func (this_frame);
377 current_pc = get_frame_pc (this_frame);
378 if (cache->pc)
379 moxie_analyze_prologue (cache->pc, current_pc, cache, this_frame);
380
381 cache->saved_sp = cache->base - cache->framesize;
382
383 for (i = 0; i < MOXIE_NUM_REGS; ++i)
384 if (cache->saved_regs[i] != REG_UNAVAIL)
385 cache->saved_regs[i] = cache->base - cache->saved_regs[i];
386
387 return cache;
388}
389
390/* Implement the "unwind_pc" gdbarch method. */
391
392static CORE_ADDR
393moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
394{
395 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
396}
397
398/* Given a GDB frame, determine the address of the calling function's
399 frame. This will be used to create a new GDB frame struct. */
400
401static void
402moxie_frame_this_id (struct frame_info *this_frame,
403 void **this_prologue_cache, struct frame_id *this_id)
404{
405 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
406 this_prologue_cache);
407
408 /* This marks the outermost frame. */
409 if (cache->base == 0)
410 return;
411
412 *this_id = frame_id_build (cache->saved_sp, cache->pc);
413}
414
415/* Get the value of register regnum in the previous stack frame. */
416
417static struct value *
418moxie_frame_prev_register (struct frame_info *this_frame,
419 void **this_prologue_cache, int regnum)
420{
421 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
422 this_prologue_cache);
423
424 gdb_assert (regnum >= 0);
425
426 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
427 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
428
429 if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
430 return frame_unwind_got_memory (this_frame, regnum,
431 cache->saved_regs[regnum]);
432
433 return frame_unwind_got_register (this_frame, regnum, regnum);
434}
435
436static const struct frame_unwind moxie_frame_unwind = {
437 NORMAL_FRAME,
438 moxie_frame_this_id,
439 moxie_frame_prev_register,
440 NULL,
441 default_frame_sniffer
442};
443
444/* Return the base address of this_frame. */
445
446static CORE_ADDR
447moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
448{
449 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
450 this_cache);
451
452 return cache->base;
453}
454
455static const struct frame_base moxie_frame_base = {
456 &moxie_frame_unwind,
457 moxie_frame_base_address,
458 moxie_frame_base_address,
459 moxie_frame_base_address
460};
461
462static struct frame_id
463moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
464{
465 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
466
467 return frame_id_build (sp, get_frame_pc (this_frame));
468}
469
470/* Allocate and initialize the moxie gdbarch object. */
471
472static struct gdbarch *
473moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
474{
475 struct gdbarch *gdbarch;
476 struct gdbarch_tdep *tdep;
477
478 /* If there is already a candidate, use it. */
479 arches = gdbarch_list_lookup_by_info (arches, &info);
480 if (arches != NULL)
481 return arches->gdbarch;
482
483 /* Allocate space for the new architecture. */
484 tdep = XMALLOC (struct gdbarch_tdep);
485 gdbarch = gdbarch_alloc (&info, tdep);
486
487 set_gdbarch_read_pc (gdbarch, moxie_read_pc);
488 set_gdbarch_write_pc (gdbarch, moxie_write_pc);
489 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
490
491 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
492 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
493 set_gdbarch_register_name (gdbarch, moxie_register_name);
494 set_gdbarch_register_type (gdbarch, moxie_register_type);
495
496 set_gdbarch_return_value (gdbarch, moxie_return_value);
497
498 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
499 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
500 set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
501 set_gdbarch_frame_align (gdbarch, moxie_frame_align);
502
503 frame_base_set_default (gdbarch, &moxie_frame_base);
504
505 /* Methods for saving / extracting a dummy frame's ID. The ID's
506 stack address must match the SP value returned by
507 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
508 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
509
510 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
511
512 set_gdbarch_print_insn (gdbarch, print_insn_moxie);
513
514 /* Hook in ABI-specific overrides, if they have been registered. */
515 gdbarch_init_osabi (info, gdbarch);
516
517 /* Hook in the default unwinders. */
518 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
519
520 /* Support simple overlay manager. */
521 set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
522
523 return gdbarch;
524}
525
526/* Register this machine's init routine. */
527
528void
529_initialize_moxie_tdep (void)
530{
531 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);
532}