1 /* Target-dependent code for Moxie.
3 Copyright (C) 2009 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
22 #include "frame-unwind.h"
23 #include "frame-base.h"
28 #include "gdb_string.h"
35 #include "arch-utils.h"
37 #include "trad-frame.h"
40 #include "gdb_assert.h"
42 #include "moxie-tdep.h"
44 /* Local functions. */
46 extern void _initialize_moxie_tdep (void);
48 /* Use an invalid address value as 'not available' marker. */
49 enum { REG_UNAVAIL
= (CORE_ADDR
) -1 };
51 struct moxie_frame_cache
57 CORE_ADDR saved_regs
[MOXIE_NUM_REGS
];
61 /* Implement the "frame_align" gdbarch method. */
64 moxie_frame_align (struct gdbarch
*gdbarch
, CORE_ADDR sp
)
66 /* Align to the size of an instruction (so that they can safely be
67 pushed onto the stack. */
71 /* Implement the "breakpoint_from_pc" gdbarch method. */
73 const static unsigned char *
74 moxie_breakpoint_from_pc (struct gdbarch
*gdbarch
,
75 CORE_ADDR
*pcptr
, int *lenptr
)
77 static unsigned char breakpoint
[] = { 0x35, 0x00 };
79 *lenptr
= sizeof (breakpoint
);
83 /* Moxie register names. */
85 char *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" };
91 /* Implement the "register_name" gdbarch method. */
94 moxie_register_name (struct gdbarch
*gdbarch
, int reg_nr
)
98 if (reg_nr
>= MOXIE_NUM_REGS
)
100 return moxie_register_names
[reg_nr
];
103 /* Implement the "register_type" gdbarch method. */
106 moxie_register_type (struct gdbarch
*gdbarch
, int reg_nr
)
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
;
113 return builtin_type (gdbarch
)->builtin_int32
;
116 /* Write into appropriate registers a function return value
117 of type TYPE, given in virtual format. */
120 moxie_store_return_value (struct type
*type
, struct regcache
*regcache
,
123 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
124 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
126 int len
= TYPE_LENGTH (type
);
128 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
129 regval
= extract_unsigned_integer (valbuf
, len
> 4 ? 4 : len
, byte_order
);
130 regcache_cooked_write_unsigned (regcache
, RET1_REGNUM
, regval
);
133 regval
= extract_unsigned_integer ((gdb_byte
*) valbuf
+ 4,
134 len
- 4, byte_order
);
135 regcache_cooked_write_unsigned (regcache
, RET1_REGNUM
+ 1, regval
);
139 /* Decode the instructions within the given address range. Decide
140 when we must have reached the end of the function prologue. If a
141 frame_info pointer is provided, fill in its saved_regs etc.
143 Returns the address of the first instruction after the prologue. */
146 moxie_analyze_prologue (CORE_ADDR start_addr
, CORE_ADDR end_addr
,
147 struct moxie_frame_cache
*cache
,
148 struct frame_info
*this_frame
)
150 struct gdbarch
*gdbarch
= get_frame_arch (this_frame
);
151 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
153 ULONGEST inst
, inst2
;
157 /* Record where the jsra instruction saves the PC and FP. */
158 cache
->saved_regs
[MOXIE_PC_REGNUM
] = -4;
159 cache
->saved_regs
[MOXIE_FP_REGNUM
] = 0;
160 cache
->framesize
= 0;
162 if (start_addr
>= end_addr
)
165 for (next_addr
= start_addr
; next_addr
< end_addr
; )
167 inst
= read_memory_unsigned_integer (next_addr
, 2, byte_order
);
169 /* Match "push $rN" where N is between 2 and 13 inclusive. */
170 if (inst
>= 0x0614 && inst
<= 0x061f)
172 regnum
= inst
& 0x000f;
173 cache
->framesize
+= 4;
174 cache
->saved_regs
[regnum
] = cache
->framesize
;
178 /* Optional stack allocation for args and local vars <= 4
180 else if (inst
== 0x01f0) /* ldi.l $r12, X */
182 offset
= read_memory_integer (next_addr
+ 2, 4, byte_order
);
183 inst2
= read_memory_unsigned_integer (next_addr
+ 6, 2, byte_order
);
185 if (inst2
== 0x051f) /* add.l $sp, $r12 */
187 cache
->framesize
+= offset
;
190 return (next_addr
+ 8);
192 else /* This is not a prologue instruction. */
199 /* Find the end of function prologue. */
202 moxie_skip_prologue (struct gdbarch
*gdbarch
, CORE_ADDR pc
)
204 CORE_ADDR func_addr
= 0, func_end
= 0;
207 /* See if we can determine the end of the prologue via the symbol table.
208 If so, then return either PC, or the PC after the prologue, whichever
210 if (find_pc_partial_function (pc
, &func_name
, &func_addr
, &func_end
))
212 CORE_ADDR post_prologue_pc
213 = skip_prologue_using_sal (gdbarch
, func_addr
);
214 if (post_prologue_pc
!= 0)
215 return max (pc
, post_prologue_pc
);
218 /* Can't determine prologue from the symbol table, need to examine
220 struct symtab_and_line sal
;
222 struct moxie_frame_cache cache
;
225 memset (&cache
, 0, sizeof cache
);
227 plg_end
= moxie_analyze_prologue (func_addr
,
228 func_end
, &cache
, NULL
);
229 /* Found a function. */
230 sym
= lookup_symbol (func_name
, NULL
, VAR_DOMAIN
, NULL
);
231 /* Don't use line number debug info for assembly source
233 if (sym
&& SYMBOL_LANGUAGE (sym
) != language_asm
)
235 sal
= find_pc_line (func_addr
, 0);
236 if (sal
.end
&& sal
.end
< func_end
)
238 /* Found a line number, use it as end of
243 /* No useable line symbol. Use result of prologue parsing
249 /* No function symbol -- just return the PC. */
250 return (CORE_ADDR
) pc
;
253 struct moxie_unwind_cache
255 /* The previous frame's inner most stack address. Used as this
256 frame ID's stack_addr. */
258 /* The frame's base, optionally used by the high-level debug info. */
261 /* How far the SP and r13 (FP) have been offset from the start of
262 the stack frame (as defined by the previous frame's stack
267 /* Table indicating the location of each and every register. */
268 struct trad_frame_saved_reg
*saved_regs
;
271 /* Implement the "read_pc" gdbarch method. */
274 moxie_read_pc (struct regcache
*regcache
)
278 regcache_cooked_read_unsigned (regcache
, MOXIE_PC_REGNUM
, &pc
);
282 /* Implement the "write_pc" gdbarch method. */
285 moxie_write_pc (struct regcache
*regcache
, CORE_ADDR val
)
287 regcache_cooked_write_unsigned (regcache
, MOXIE_PC_REGNUM
, val
);
290 /* Implement the "unwind_pc" gdbarch method. */
293 moxie_unwind_sp (struct gdbarch
*gdbarch
, struct frame_info
*next_frame
)
295 return frame_unwind_register_unsigned (next_frame
, MOXIE_SP_REGNUM
);
298 /* Given a return value in `regbuf' with a type `valtype',
299 extract and copy its value into `valbuf'. */
302 moxie_extract_return_value (struct type
*type
, struct regcache
*regcache
,
305 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
306 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
307 bfd_byte
*valbuf
= dst
;
308 int len
= TYPE_LENGTH (type
);
311 /* By using store_unsigned_integer we avoid having to do
312 anything special for small big-endian values. */
313 regcache_cooked_read_unsigned (regcache
, RET1_REGNUM
, &tmp
);
314 store_unsigned_integer (valbuf
, (len
> 4 ? len
- 4 : len
), byte_order
, tmp
);
316 /* Ignore return values more than 8 bytes in size because the moxie
317 returns anything more than 8 bytes in the stack. */
320 regcache_cooked_read_unsigned (regcache
, RET1_REGNUM
+ 1, &tmp
);
321 store_unsigned_integer (valbuf
+ len
- 4, 4, byte_order
, tmp
);
325 /* Implement the "return_value" gdbarch method. */
327 static enum return_value_convention
328 moxie_return_value (struct gdbarch
*gdbarch
, struct type
*func_type
,
329 struct type
*valtype
, struct regcache
*regcache
,
330 gdb_byte
*readbuf
, const gdb_byte
*writebuf
)
332 if (TYPE_LENGTH (valtype
) > 8)
333 return RETURN_VALUE_STRUCT_CONVENTION
;
337 moxie_extract_return_value (valtype
, regcache
, readbuf
);
338 if (writebuf
!= NULL
)
339 moxie_store_return_value (valtype
, regcache
, writebuf
);
340 return RETURN_VALUE_REGISTER_CONVENTION
;
344 /* Allocate and initialize a moxie_frame_cache object. */
346 static struct moxie_frame_cache
*
347 moxie_alloc_frame_cache (void)
349 struct moxie_frame_cache
*cache
;
352 cache
= FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache
);
357 cache
->framesize
= 0;
358 for (i
= 0; i
< MOXIE_NUM_REGS
; ++i
)
359 cache
->saved_regs
[i
] = REG_UNAVAIL
;
364 /* Populate a moxie_frame_cache object for this_frame. */
366 static struct moxie_frame_cache
*
367 moxie_frame_cache (struct frame_info
*this_frame
, void **this_cache
)
369 struct moxie_frame_cache
*cache
;
370 CORE_ADDR current_pc
;
376 cache
= moxie_alloc_frame_cache ();
379 cache
->base
= get_frame_register_unsigned (this_frame
, MOXIE_FP_REGNUM
);
380 if (cache
->base
== 0)
383 cache
->pc
= get_frame_func (this_frame
);
384 current_pc
= get_frame_pc (this_frame
);
386 moxie_analyze_prologue (cache
->pc
, current_pc
, cache
, this_frame
);
388 cache
->saved_sp
= cache
->base
- cache
->framesize
;
390 for (i
= 0; i
< MOXIE_NUM_REGS
; ++i
)
391 if (cache
->saved_regs
[i
] != REG_UNAVAIL
)
392 cache
->saved_regs
[i
] = cache
->base
- cache
->saved_regs
[i
];
397 /* Implement the "unwind_pc" gdbarch method. */
400 moxie_unwind_pc (struct gdbarch
*gdbarch
, struct frame_info
*next_frame
)
402 return frame_unwind_register_unsigned (next_frame
, MOXIE_PC_REGNUM
);
405 /* Given a GDB frame, determine the address of the calling function's
406 frame. This will be used to create a new GDB frame struct. */
409 moxie_frame_this_id (struct frame_info
*this_frame
,
410 void **this_prologue_cache
, struct frame_id
*this_id
)
412 struct moxie_frame_cache
*cache
= moxie_frame_cache (this_frame
,
413 this_prologue_cache
);
415 /* This marks the outermost frame. */
416 if (cache
->base
== 0)
419 *this_id
= frame_id_build (cache
->saved_sp
, cache
->pc
);
422 /* Get the value of register regnum in the previous stack frame. */
424 static struct value
*
425 moxie_frame_prev_register (struct frame_info
*this_frame
,
426 void **this_prologue_cache
, int regnum
)
428 struct moxie_frame_cache
*cache
= moxie_frame_cache (this_frame
,
429 this_prologue_cache
);
431 gdb_assert (regnum
>= 0);
433 if (regnum
== MOXIE_SP_REGNUM
&& cache
->saved_sp
)
434 return frame_unwind_got_constant (this_frame
, regnum
, cache
->saved_sp
);
436 if (regnum
< MOXIE_NUM_REGS
&& cache
->saved_regs
[regnum
] != REG_UNAVAIL
)
437 return frame_unwind_got_memory (this_frame
, regnum
,
438 cache
->saved_regs
[regnum
]);
440 return frame_unwind_got_register (this_frame
, regnum
, regnum
);
443 static const struct frame_unwind moxie_frame_unwind
= {
446 moxie_frame_prev_register
,
448 default_frame_sniffer
451 /* Return the base address of this_frame. */
454 moxie_frame_base_address (struct frame_info
*this_frame
, void **this_cache
)
456 struct moxie_frame_cache
*cache
= moxie_frame_cache (this_frame
,
462 static const struct frame_base moxie_frame_base
= {
464 moxie_frame_base_address
,
465 moxie_frame_base_address
,
466 moxie_frame_base_address
469 static struct frame_id
470 moxie_dummy_id (struct gdbarch
*gdbarch
, struct frame_info
*this_frame
)
472 CORE_ADDR sp
= get_frame_register_unsigned (this_frame
, MOXIE_SP_REGNUM
);
474 return frame_id_build (sp
, get_frame_pc (this_frame
));
477 /* Allocate and initialize the moxie gdbarch object. */
479 static struct gdbarch
*
480 moxie_gdbarch_init (struct gdbarch_info info
, struct gdbarch_list
*arches
)
482 struct gdbarch
*gdbarch
;
483 struct gdbarch_tdep
*tdep
;
485 /* If there is already a candidate, use it. */
486 arches
= gdbarch_list_lookup_by_info (arches
, &info
);
488 return arches
->gdbarch
;
490 /* Allocate space for the new architecture. */
491 tdep
= XMALLOC (struct gdbarch_tdep
);
492 gdbarch
= gdbarch_alloc (&info
, tdep
);
494 set_gdbarch_read_pc (gdbarch
, moxie_read_pc
);
495 set_gdbarch_write_pc (gdbarch
, moxie_write_pc
);
496 set_gdbarch_unwind_sp (gdbarch
, moxie_unwind_sp
);
498 set_gdbarch_num_regs (gdbarch
, MOXIE_NUM_REGS
);
499 set_gdbarch_sp_regnum (gdbarch
, MOXIE_SP_REGNUM
);
500 set_gdbarch_register_name (gdbarch
, moxie_register_name
);
501 set_gdbarch_register_type (gdbarch
, moxie_register_type
);
503 set_gdbarch_return_value (gdbarch
, moxie_return_value
);
505 set_gdbarch_skip_prologue (gdbarch
, moxie_skip_prologue
);
506 set_gdbarch_inner_than (gdbarch
, core_addr_lessthan
);
507 set_gdbarch_breakpoint_from_pc (gdbarch
, moxie_breakpoint_from_pc
);
508 set_gdbarch_frame_align (gdbarch
, moxie_frame_align
);
510 frame_base_set_default (gdbarch
, &moxie_frame_base
);
512 /* Methods for saving / extracting a dummy frame's ID. The ID's
513 stack address must match the SP value returned by
514 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
515 set_gdbarch_dummy_id (gdbarch
, moxie_dummy_id
);
517 set_gdbarch_unwind_pc (gdbarch
, moxie_unwind_pc
);
519 set_gdbarch_print_insn (gdbarch
, print_insn_moxie
);
521 /* Hook in ABI-specific overrides, if they have been registered. */
522 gdbarch_init_osabi (info
, gdbarch
);
524 /* Hook in the default unwinders. */
525 frame_unwind_append_unwinder (gdbarch
, &moxie_frame_unwind
);
527 /* Support simple overlay manager. */
528 set_gdbarch_overlay_update (gdbarch
, simple_overlay_update
);
533 /* Register this machine's init routine. */
536 _initialize_moxie_tdep (void)
538 register_gdbarch_init (bfd_arch_moxie
, moxie_gdbarch_init
);