/* Target-dependent code for Morpho mt processor, for GDB.
- Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Contributed by Michael Snyder, msnyder@redhat.com. */
#include "dwarf2-frame.h"
#include "infcall.h"
#include "gdb_assert.h"
+#include "language.h"
enum mt_arch_constants
{
/* Return name of register number specified by REGNUM. */
static const char *
-mt_register_name (int regnum)
+mt_register_name (struct gdbarch *gdbarch, int regnum)
{
static const char *const register_names[] = {
/* CPU regs. */
if (group == all_reggroup)
return (regnum >= 0
&& regnum < MT_NUM_REGS + MT_NUM_PSEUDO_REGS
- && mt_register_name (regnum)[0] != '\0');
+ && mt_register_name (gdbarch, regnum)[0] != '\0');
if (group == general_reggroup)
return (regnum >= MT_R0_REGNUM && regnum <= MT_R15_REGNUM);
values. */
static enum return_value_convention
-mt_return_value (struct gdbarch *gdbarch, struct type *type,
- struct regcache *regcache, gdb_byte *readbuf,
- const gdb_byte *writebuf)
+mt_return_value (struct gdbarch *gdbarch, struct type *func_type,
+ struct type *type, struct regcache *regcache,
+ gdb_byte *readbuf, const gdb_byte *writebuf)
{
if (TYPE_LENGTH (type) > 4)
{
call. */
static CORE_ADDR
-mt_skip_prologue (CORE_ADDR pc)
+mt_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0, func_end = 0;
char *func_name;
struct symbol *sym;
/* Found a function. */
- sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL, NULL);
+ sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
{
/* Don't use this trick for assembly source files. */
The BP for ms2 is defined as 0x69000000 (illegal) */
static const gdb_byte *
-mt_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
+mt_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
+ int *bp_size)
{
static gdb_byte ms1_breakpoint[] = { 0x68, 0, 0, 0 };
static gdb_byte ms2_breakpoint[] = { 0x69, 0, 0, 0 };
*bp_size = 4;
- if (gdbarch_bfd_arch_info (current_gdbarch)->mach == bfd_mach_ms2)
+ if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
return ms2_breakpoint;
return ms1_breakpoint;
static void
mt_registers_info (struct gdbarch *gdbarch,
- struct ui_file *file,
- struct frame_info *frame, int regnum, int all)
+ struct ui_file *file,
+ struct frame_info *frame, int regnum, int all)
{
if (regnum == -1)
{
frame_register_read (frame, regnum, buff);
- fputs_filtered (REGISTER_NAME (regnum), file);
- print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
+ fputs_filtered (gdbarch_register_name
+ (gdbarch, regnum), file);
+ print_spaces_filtered (15 - strlen (gdbarch_register_name
+ (gdbarch, regnum)),
+ file);
fputs_filtered ("0x", file);
for (i = 0; i < regsize; i++)
frame_register_read (frame, MT_COPRO_REGNUM, buf);
/* And print. */
regnum = MT_COPRO_PSEUDOREG_REGNUM;
- fputs_filtered (REGISTER_NAME (regnum), file);
- print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
+ fputs_filtered (gdbarch_register_name (gdbarch, regnum),
+ file);
+ print_spaces_filtered (15 - strlen (gdbarch_register_name
+ (gdbarch, regnum)),
+ file);
val_print (register_type (gdbarch, regnum), buf,
- 0, 0, file, 0, 1, 0, Val_no_prettyprint);
+ 0, 0, file, 0, 1, 0, Val_no_prettyprint,
+ current_language);
fputs_filtered ("\n", file);
}
else if (regnum == MT_MAC_REGNUM || regnum == MT_MAC_PSEUDOREG_REGNUM)
/* And print. */
regnum = MT_MAC_PSEUDOREG_REGNUM;
- fputs_filtered (REGISTER_NAME (regnum), file);
- print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
+ fputs_filtered (gdbarch_register_name (gdbarch, regnum),
+ file);
+ print_spaces_filtered (15 - strlen (gdbarch_register_name
+ (gdbarch, regnum)),
+ file);
fputs_filtered ("0x", file);
print_longest (file, 'x', 0, newmac);
fputs_filtered ("\t", file);
the frame. */
static struct mt_unwind_cache *
-mt_frame_unwind_cache (struct frame_info *next_frame,
+mt_frame_unwind_cache (struct frame_info *this_frame,
void **this_prologue_cache)
{
struct gdbarch *gdbarch;
if ((*this_prologue_cache))
return (*this_prologue_cache);
- gdbarch = get_frame_arch (next_frame);
+ gdbarch = get_frame_arch (this_frame);
info = FRAME_OBSTACK_ZALLOC (struct mt_unwind_cache);
(*this_prologue_cache) = info;
info->framesize = 0;
info->frame_base = 0;
info->frameless_p = 1;
- info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+ info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
/* Grab the frame-relative values of SP and FP, needed below.
The frame_saved_register function will find them on the
stack or in the registers as appropriate. */
- frame_unwind_unsigned_register (next_frame, MT_SP_REGNUM, &sp);
- frame_unwind_unsigned_register (next_frame, MT_FP_REGNUM, &fp);
+ sp = get_frame_register_unsigned (this_frame, MT_SP_REGNUM);
+ fp = get_frame_register_unsigned (this_frame, MT_FP_REGNUM);
- start_addr = frame_func_unwind (next_frame, NORMAL_FRAME);
+ start_addr = get_frame_func (this_frame);
/* Return early if GDB couldn't find the function. */
if (start_addr == 0)
return info;
- end_addr = frame_pc_unwind (next_frame);
+ end_addr = get_frame_pc (this_frame);
prologue_end_addr = skip_prologue_using_sal (start_addr);
if (end_addr == 0)
for (next_addr = start_addr; next_addr < end_addr; next_addr += 4)
{
- instr = get_frame_memory_unsigned (next_frame, next_addr, 4);
+ instr = get_frame_memory_unsigned (this_frame, next_addr, 4);
if (delayed_store) /* previous instr was a push */
{
upper_half = delayed_store >> 16;
{
ULONGEST pc;
- frame_unwind_unsigned_register (next_frame, MT_PC_REGNUM, &pc);
+ pc = frame_unwind_register_unsigned (next_frame, MT_PC_REGNUM);
return pc;
}
{
ULONGEST sp;
- frame_unwind_unsigned_register (next_frame, MT_SP_REGNUM, &sp);
+ sp = frame_unwind_register_unsigned (next_frame, MT_SP_REGNUM);
return sp;
}
-/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
- dummy frame. The frame ID's base needs to match the TOS value
- saved by save_dummy_frame_tos(), and the PC match the dummy frame's
- breakpoint. */
+/* Assuming THIS_FRAME is a dummy, return the frame ID of that dummy
+ frame. The frame ID's base needs to match the TOS value saved by
+ save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint. */
static struct frame_id
-mt_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+mt_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
- return frame_id_build (mt_unwind_sp (gdbarch, next_frame),
- frame_pc_unwind (next_frame));
+ CORE_ADDR sp = get_frame_register_unsigned (this_frame, MT_SP_REGNUM);
+ return frame_id_build (sp, get_frame_pc (this_frame));
}
/* Given a GDB frame, determine the address of the calling function's
frame. This will be used to create a new GDB frame struct. */
static void
-mt_frame_this_id (struct frame_info *next_frame,
+mt_frame_this_id (struct frame_info *this_frame,
void **this_prologue_cache, struct frame_id *this_id)
{
struct mt_unwind_cache *info =
- mt_frame_unwind_cache (next_frame, this_prologue_cache);
+ mt_frame_unwind_cache (this_frame, this_prologue_cache);
if (!(info == NULL || info->prev_sp == 0))
- (*this_id) = frame_id_build (info->prev_sp,
- frame_func_unwind (next_frame, NORMAL_FRAME));
+ (*this_id) = frame_id_build (info->prev_sp, get_frame_func (this_frame));
return;
}
-static void
-mt_frame_prev_register (struct frame_info *next_frame,
- void **this_prologue_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *bufferp)
+static struct value *
+mt_frame_prev_register (struct frame_info *this_frame,
+ void **this_prologue_cache, int regnum)
{
struct mt_unwind_cache *info =
- mt_frame_unwind_cache (next_frame, this_prologue_cache);
+ mt_frame_unwind_cache (this_frame, this_prologue_cache);
- trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
- optimizedp, lvalp, addrp, realnump, bufferp);
+ return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}
static CORE_ADDR
-mt_frame_base_address (struct frame_info *next_frame,
+mt_frame_base_address (struct frame_info *this_frame,
void **this_prologue_cache)
{
struct mt_unwind_cache *info =
- mt_frame_unwind_cache (next_frame, this_prologue_cache);
+ mt_frame_unwind_cache (this_frame, this_prologue_cache);
return info->frame_base;
}
static const struct frame_unwind mt_frame_unwind = {
NORMAL_FRAME,
mt_frame_this_id,
- mt_frame_prev_register
+ mt_frame_prev_register,
+ NULL,
+ default_frame_sniffer
};
-/* The sniffer is a registered function that identifies our family of
- frame unwind functions (this_id and prev_register). */
-
-static const struct frame_unwind *
-mt_frame_sniffer (struct frame_info *next_frame)
-{
- return &mt_frame_unwind;
-}
-
/* Another shared interface: the 'frame_base' object specifies how to
unwind a frame and secure the base addresses for frame objects
(locals, args). */
/* Register the DWARF 2 sniffer first, and then the traditional prologue
based sniffer. */
- frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
- frame_unwind_append_sniffer (gdbarch, mt_frame_sniffer);
+ dwarf2_append_unwinders (gdbarch);
+ frame_unwind_append_unwinder (gdbarch, &mt_frame_unwind);
frame_base_set_default (gdbarch, &mt_frame_base);
/* Register the 'unwind_pc' method. */
/* Methods for saving / extracting a dummy frame's ID.
The ID's stack address must match the SP value returned by
PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
- set_gdbarch_unwind_dummy_id (gdbarch, mt_unwind_dummy_id);
+ set_gdbarch_dummy_id (gdbarch, mt_dummy_id);
return gdbarch;
}