-/* Print VAX instructions for GDB, the GNU debugger.
- Copyright 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000, 2002, 2003
- Free Software Foundation, Inc.
+/* Target-dependent code for the VAX.
+
+ Copyright (C) 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000, 2002,
+ 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of GDB.
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., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
-#include "symtab.h"
-#include "opcode/vax.h"
+#include "arch-utils.h"
+#include "dis-asm.h"
+#include "floatformat.h"
+#include "frame.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
#include "gdbcore.h"
-#include "inferior.h"
+#include "gdbtypes.h"
+#include "osabi.h"
#include "regcache.h"
-#include "frame.h"
+#include "regset.h"
+#include "trad-frame.h"
#include "value.h"
-#include "arch-utils.h"
+
#include "gdb_string.h"
-#include "osabi.h"
-#include "dis-asm.h"
#include "vax-tdep.h"
-static gdbarch_register_name_ftype vax_register_name;
-
-static gdbarch_skip_prologue_ftype vax_skip_prologue;
-static gdbarch_frame_num_args_ftype vax_frame_num_args;
-static gdbarch_deprecated_frame_chain_ftype vax_frame_chain;
-
-static gdbarch_deprecated_extract_return_value_ftype vax_extract_return_value;
-static gdbarch_deprecated_extract_struct_value_address_ftype
- vax_extract_struct_value_address;
+/* Return the name of register REGNUM. */
-static gdbarch_deprecated_push_dummy_frame_ftype vax_push_dummy_frame;
-\f
static const char *
-vax_register_name (int regno)
+vax_register_name (int regnum)
{
static char *register_names[] =
{
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",
"ps",
};
- if (regno < 0)
- return (NULL);
- if (regno >= (sizeof(register_names) / sizeof(*register_names)))
- return (NULL);
- return (register_names[regno]);
+ if (regnum >= 0 && regnum < ARRAY_SIZE (register_names))
+ return register_names[regnum];
+
+ return NULL;
}
-static int
-vax_register_byte (int regno)
+/* Return the GDB type object for the "standard" data type of data in
+ register REGNUM. */
+
+static struct type *
+vax_register_type (struct gdbarch *gdbarch, int regnum)
{
- return (regno * 4);
+ return builtin_type_int;
}
+\f
+/* Core file support. */
-static int
-vax_register_raw_size (int regno)
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+vax_supply_gregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
{
- return (4);
+ const gdb_byte *regs = gregs;
+ int i;
+
+ for (i = 0; i < VAX_NUM_REGS; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + i * 4);
+ }
}
-static int
-vax_register_virtual_size (int regno)
+/* VAX register set. */
+
+static struct regset vax_gregset =
{
- return (4);
-}
+ NULL,
+ vax_supply_gregset
+};
-static struct type *
-vax_register_virtual_type (int regno)
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+
+static const struct regset *
+vax_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
{
- return (builtin_type_int);
+ if (strcmp (sect_name, ".reg") == 0 && sect_size >= VAX_NUM_REGS * 4)
+ return &vax_gregset;
+
+ return NULL;
}
\f
-static void
-vax_frame_init_saved_regs (struct frame_info *frame)
-{
- int regnum, regmask;
- CORE_ADDR next_addr;
+/* The VAX UNIX calling convention uses R1 to pass a structure return
+ value address instead of passing it as a first (hidden) argument as
+ the VMS calling convention suggests. */
- if (deprecated_get_frame_saved_regs (frame))
- return;
-
- frame_saved_regs_zalloc (frame);
-
- regmask = read_memory_integer (get_frame_base (frame) + 4, 4) >> 16;
+static CORE_ADDR
+vax_store_arguments (struct regcache *regcache, int nargs,
+ struct value **args, CORE_ADDR sp)
+{
+ gdb_byte buf[4];
+ int count = 0;
+ int i;
- next_addr = get_frame_base (frame) + 16;
+ /* We create an argument list on the stack, and make the argument
+ pointer to it. */
- /* regmask's low bit is for register 0, which is the first one
- what would be pushed. */
- for (regnum = 0; regnum < VAX_AP_REGNUM; regnum++)
+ /* Push arguments in reverse order. */
+ for (i = nargs - 1; i >= 0; i--)
{
- if (regmask & (1 << regnum))
- deprecated_get_frame_saved_regs (frame)[regnum] = next_addr += 4;
+ int len = TYPE_LENGTH (value_enclosing_type (args[i]));
+
+ sp -= (len + 3) & ~3;
+ count += (len + 3) / 4;
+ write_memory (sp, value_contents_all (args[i]), len);
}
- deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = next_addr + 4;
- if (regmask & (1 << DEPRECATED_FP_REGNUM))
- deprecated_get_frame_saved_regs (frame)[SP_REGNUM] +=
- 4 + (4 * read_memory_integer (next_addr + 4, 4));
+ /* Push argument count. */
+ sp -= 4;
+ store_unsigned_integer (buf, 4, count);
+ write_memory (sp, buf, 4);
- deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = get_frame_base (frame) + 16;
- deprecated_get_frame_saved_regs (frame)[DEPRECATED_FP_REGNUM] = get_frame_base (frame) + 12;
- deprecated_get_frame_saved_regs (frame)[VAX_AP_REGNUM] = get_frame_base (frame) + 8;
- deprecated_get_frame_saved_regs (frame)[PS_REGNUM] = get_frame_base (frame) + 4;
-}
+ /* Update the argument pointer. */
+ store_unsigned_integer (buf, 4, sp);
+ regcache_cooked_write (regcache, VAX_AP_REGNUM, buf);
-/* Get saved user PC for sigtramp from sigcontext for BSD style sigtramp. */
+ return sp;
+}
static CORE_ADDR
-vax_sigtramp_saved_pc (struct frame_info *frame)
+vax_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+ struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+ struct value **args, CORE_ADDR sp, int struct_return,
+ CORE_ADDR struct_addr)
{
- CORE_ADDR sigcontext_addr;
- char *buf;
- int ptrbytes = TYPE_LENGTH (builtin_type_void_func_ptr);
- int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
-
- buf = alloca (ptrbytes);
- /* Get sigcontext address, it is the third parameter on the stack. */
- if (get_next_frame (frame))
- sigcontext_addr = read_memory_typed_address
- (DEPRECATED_FRAME_ARGS_ADDRESS (get_next_frame (frame))
- + FRAME_ARGS_SKIP + sigcontext_offs,
- builtin_type_void_data_ptr);
- else
- sigcontext_addr = read_memory_typed_address
- (read_register (SP_REGNUM) + sigcontext_offs, builtin_type_void_data_ptr);
-
- /* Don't cause a memory_error when accessing sigcontext in case the stack
- layout has changed or the stack is corrupt. */
- target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes);
- return extract_typed_address (buf, builtin_type_void_func_ptr);
+ CORE_ADDR fp = sp;
+ gdb_byte buf[4];
+
+ /* Set up the function arguments. */
+ sp = vax_store_arguments (regcache, nargs, args, sp);
+
+ /* Store return value address. */
+ if (struct_return)
+ regcache_cooked_write_unsigned (regcache, VAX_R1_REGNUM, struct_addr);
+
+ /* Store return address in the PC slot. */
+ sp -= 4;
+ store_unsigned_integer (buf, 4, bp_addr);
+ write_memory (sp, buf, 4);
+
+ /* Store the (fake) frame pointer in the FP slot. */
+ sp -= 4;
+ store_unsigned_integer (buf, 4, fp);
+ write_memory (sp, buf, 4);
+
+ /* Skip the AP slot. */
+ sp -= 4;
+
+ /* Store register save mask and control bits. */
+ sp -= 4;
+ store_unsigned_integer (buf, 4, 0);
+ write_memory (sp, buf, 4);
+
+ /* Store condition handler. */
+ sp -= 4;
+ store_unsigned_integer (buf, 4, 0);
+ write_memory (sp, buf, 4);
+
+ /* Update the stack pointer and frame pointer. */
+ store_unsigned_integer (buf, 4, sp);
+ regcache_cooked_write (regcache, VAX_SP_REGNUM, buf);
+ regcache_cooked_write (regcache, VAX_FP_REGNUM, buf);
+
+ /* Return the saved (fake) frame pointer. */
+ return fp;
}
-static CORE_ADDR
-vax_frame_saved_pc (struct frame_info *frame)
+static struct frame_id
+vax_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
- if ((get_frame_type (frame) == SIGTRAMP_FRAME))
- return (vax_sigtramp_saved_pc (frame)); /* XXXJRT */
+ CORE_ADDR fp;
- return (read_memory_integer (get_frame_base (frame) + 16, 4));
+ fp = frame_unwind_register_unsigned (next_frame, VAX_FP_REGNUM);
+ return frame_id_build (fp, frame_pc_unwind (next_frame));
}
+\f
-static CORE_ADDR
-vax_frame_args_address (struct frame_info *frame)
+static enum return_value_convention
+vax_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, gdb_byte *readbuf,
+ const gdb_byte *writebuf)
{
- /* In most of GDB, getting the args address is too important to just
- say "I don't know". This is sometimes wrong for functions that
- aren't on top of the stack, but c'est la vie. */
- if (get_next_frame (frame))
- return (read_memory_integer (get_frame_base (get_next_frame (frame)) + 8, 4));
- /* Cannot find the AP register value directly from the FP value.
- Must find it saved in the frame called by this one, or in the AP
- register for the innermost frame. However, there is no way to
- tell the difference between the innermost frame and a frame for
- which we just don't know the frame that it called (e.g. "info
- frame 0x7ffec789"). For the sake of argument, suppose that the
- stack is somewhat trashed (which is one reason that "info frame"
- exists). So, return 0 (indicating we don't know the address of
- the arglist) if we don't know what frame this frame calls. */
- return 0;
+ int len = TYPE_LENGTH (type);
+ gdb_byte buf[8];
+
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION
+ || TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ /* The default on VAX is to return structures in static memory.
+ Consequently a function must return the address where we can
+ find the return value. */
+
+ if (readbuf)
+ {
+ ULONGEST addr;
+
+ regcache_raw_read_unsigned (regcache, VAX_R0_REGNUM, &addr);
+ read_memory (addr, readbuf, len);
+ }
+
+ return RETURN_VALUE_ABI_RETURNS_ADDRESS;
+ }
+
+ if (readbuf)
+ {
+ /* Read the contents of R0 and (if necessary) R1. */
+ regcache_cooked_read (regcache, VAX_R0_REGNUM, buf);
+ if (len > 4)
+ regcache_cooked_read (regcache, VAX_R1_REGNUM, buf + 4);
+ memcpy (readbuf, buf, len);
+ }
+ if (writebuf)
+ {
+ /* Read the contents to R0 and (if necessary) R1. */
+ memcpy (buf, writebuf, len);
+ regcache_cooked_write (regcache, VAX_R0_REGNUM, buf);
+ if (len > 4)
+ regcache_cooked_write (regcache, VAX_R1_REGNUM, buf + 4);
+ }
+
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
+\f
-static int
-vax_frame_num_args (struct frame_info *fi)
+/* Use the program counter to determine the contents and size of a
+ breakpoint instruction. Return a pointer to a string of bytes that
+ encode a breakpoint instruction, store the length of the string in
+ *LEN and optionally adjust *PC to point to the correct memory
+ location for inserting the breakpoint. */
+
+static const gdb_byte *
+vax_breakpoint_from_pc (CORE_ADDR *pc, int *len)
{
- return (0xff & read_memory_integer (DEPRECATED_FRAME_ARGS_ADDRESS (fi), 1));
+ static gdb_byte break_insn[] = { 3 };
+
+ *len = sizeof (break_insn);
+ return break_insn;
}
+\f
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
static CORE_ADDR
-vax_frame_chain (struct frame_info *frame)
+vax_skip_prologue (CORE_ADDR pc)
{
- /* In the case of the VAX, the frame's nominal address is the FP value,
- and 12 bytes later comes the saved previous FP value as a 4-byte word. */
- if (deprecated_inside_entry_file (get_frame_pc (frame)))
- return (0);
+ gdb_byte op = read_memory_unsigned_integer (pc, 1);
+
+ if (op == 0x11)
+ pc += 2; /* skip brb */
+ if (op == 0x31)
+ pc += 3; /* skip brw */
+ if (op == 0xC2
+ && (read_memory_unsigned_integer (pc + 2, 1)) == 0x5E)
+ pc += 3; /* skip subl2 */
+ if (op == 0x9E
+ && (read_memory_unsigned_integer (pc + 1, 1)) == 0xAE
+ && (read_memory_unsigned_integer (pc + 3, 1)) == 0x5E)
+ pc += 4; /* skip movab */
+ if (op == 0x9E
+ && (read_memory_unsigned_integer (pc + 1, 1)) == 0xCE
+ && (read_memory_unsigned_integer (pc + 4, 1)) == 0x5E)
+ pc += 5; /* skip movab */
+ if (op == 0x9E
+ && (read_memory_unsigned_integer (pc + 1, 1)) == 0xEE
+ && (read_memory_unsigned_integer (pc + 6, 1)) == 0x5E)
+ pc += 7; /* skip movab */
- return (read_memory_integer (get_frame_base (frame) + 12, 4));
+ return pc;
}
\f
-static void
-vax_push_dummy_frame (void)
+
+/* Unwinding the stack is relatively easy since the VAX has a
+ dedicated frame pointer, and frames are set up automatically as the
+ result of a function call. Most of the relevant information can be
+ inferred from the documentation of the Procedure Call Instructions
+ in the VAX MACRO and Instruction Set Reference Manual. */
+
+struct vax_frame_cache
{
- CORE_ADDR sp = read_register (SP_REGNUM);
- int regnum;
+ /* Base address. */
+ CORE_ADDR base;
- sp = push_word (sp, 0); /* arglist */
- for (regnum = 11; regnum >= 0; regnum--)
- sp = push_word (sp, read_register (regnum));
- sp = push_word (sp, read_register (PC_REGNUM));
- sp = push_word (sp, read_register (DEPRECATED_FP_REGNUM));
- sp = push_word (sp, read_register (VAX_AP_REGNUM));
- sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef) + 0x2fff0000);
- sp = push_word (sp, 0);
- write_register (SP_REGNUM, sp);
- write_register (DEPRECATED_FP_REGNUM, sp);
- write_register (VAX_AP_REGNUM, sp + (17 * 4));
-}
+ /* Table of saved registers. */
+ struct trad_frame_saved_reg *saved_regs;
+};
-static void
-vax_pop_frame (void)
+struct vax_frame_cache *
+vax_frame_cache (struct frame_info *next_frame, void **this_cache)
{
- CORE_ADDR fp = read_register (DEPRECATED_FP_REGNUM);
+ struct vax_frame_cache *cache;
+ CORE_ADDR addr;
+ ULONGEST mask;
int regnum;
- int regmask = read_memory_integer (fp + 4, 4);
-
- write_register (PS_REGNUM,
- (regmask & 0xffff)
- | (read_register (PS_REGNUM) & 0xffff0000));
- write_register (PC_REGNUM, read_memory_integer (fp + 16, 4));
- write_register (DEPRECATED_FP_REGNUM, read_memory_integer (fp + 12, 4));
- write_register (VAX_AP_REGNUM, read_memory_integer (fp + 8, 4));
- fp += 16;
- for (regnum = 0; regnum < 12; regnum++)
- if (regmask & (0x10000 << regnum))
- write_register (regnum, read_memory_integer (fp += 4, 4));
- fp = fp + 4 + ((regmask >> 30) & 3);
- if (regmask & 0x20000000)
+
+ if (*this_cache)
+ return *this_cache;
+
+ /* Allocate a new cache. */
+ cache = FRAME_OBSTACK_ZALLOC (struct vax_frame_cache);
+ cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+ /* The frame pointer is used as the base for the frame. */
+ cache->base = frame_unwind_register_unsigned (next_frame, VAX_FP_REGNUM);
+ if (cache->base == 0)
+ return cache;
+
+ /* The register save mask and control bits determine the layout of
+ the stack frame. */
+ mask = get_frame_memory_unsigned (next_frame, cache->base + 4, 4) >> 16;
+
+ /* These are always saved. */
+ cache->saved_regs[VAX_PC_REGNUM].addr = cache->base + 16;
+ cache->saved_regs[VAX_FP_REGNUM].addr = cache->base + 12;
+ cache->saved_regs[VAX_AP_REGNUM].addr = cache->base + 8;
+ cache->saved_regs[VAX_PS_REGNUM].addr = cache->base + 4;
+
+ /* Scan the register save mask and record the location of the saved
+ registers. */
+ addr = cache->base + 20;
+ for (regnum = 0; regnum < VAX_AP_REGNUM; regnum++)
{
- regnum = read_memory_integer (fp, 4);
- fp += (regnum + 1) * 4;
+ if (mask & (1 << regnum))
+ {
+ cache->saved_regs[regnum].addr = addr;
+ addr += 4;
+ }
}
- write_register (SP_REGNUM, fp);
- flush_cached_frames ();
-}
-/* The VAX call dummy sequence:
+ /* The CALLS/CALLG flag determines whether this frame has a General
+ Argument List or a Stack Argument List. */
+ if (mask & (1 << 13))
+ {
+ ULONGEST numarg;
+
+ /* This is a procedure with Stack Argument List. Adjust the
+ stack address for the arguments that were pushed onto the
+ stack. The return instruction will automatically pop the
+ arguments from the stack. */
+ numarg = get_frame_memory_unsigned (next_frame, addr, 1);
+ addr += 4 + numarg * 4;
+ }
- calls #69, @#32323232
- bpt
+ /* Bits 1:0 of the stack pointer were saved in the control bits. */
+ trad_frame_set_value (cache->saved_regs, VAX_SP_REGNUM, addr + (mask >> 14));
- It is 8 bytes long. The address and argc are patched by
- vax_fix_call_dummy(). */
-static LONGEST vax_call_dummy_words[] = { 0x329f69fb, 0x03323232 };
-static int sizeof_vax_call_dummy_words = sizeof(vax_call_dummy_words);
+ return cache;
+}
static void
-vax_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
- struct value **args, struct type *type, int gcc_p)
+vax_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ struct frame_id *this_id)
{
- dummy[1] = nargs;
- store_unsigned_integer (dummy + 3, 4, fun);
+ struct vax_frame_cache *cache = vax_frame_cache (next_frame, this_cache);
+
+ /* This marks the outermost frame. */
+ if (cache->base == 0)
+ return;
+
+ (*this_id) = frame_id_build (cache->base,
+ frame_func_unwind (next_frame, NORMAL_FRAME));
}
-\f
+
static void
-vax_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+vax_frame_prev_register (struct frame_info *next_frame, void **this_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, gdb_byte *valuep)
{
- write_register (1, addr);
+ struct vax_frame_cache *cache = vax_frame_cache (next_frame, this_cache);
+
+ trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
}
-static void
-vax_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
+static const struct frame_unwind vax_frame_unwind =
{
- memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (0), TYPE_LENGTH (valtype));
+ NORMAL_FRAME,
+ vax_frame_this_id,
+ vax_frame_prev_register
+};
+
+static const struct frame_unwind *
+vax_frame_sniffer (struct frame_info *next_frame)
+{
+ return &vax_frame_unwind;
}
+\f
-static void
-vax_store_return_value (struct type *valtype, char *valbuf)
+static CORE_ADDR
+vax_frame_base_address (struct frame_info *next_frame, void **this_cache)
{
- deprecated_write_register_bytes (0, valbuf, TYPE_LENGTH (valtype));
+ struct vax_frame_cache *cache = vax_frame_cache (next_frame, this_cache);
+
+ return cache->base;
}
static CORE_ADDR
-vax_extract_struct_value_address (char *regbuf)
+vax_frame_args_address (struct frame_info *next_frame, void **this_cache)
{
- return (extract_unsigned_integer (regbuf + DEPRECATED_REGISTER_BYTE (0),
- DEPRECATED_REGISTER_RAW_SIZE (0)));
+ return frame_unwind_register_unsigned (next_frame, VAX_AP_REGNUM);
}
-\f
-static const unsigned char *
-vax_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+
+static const struct frame_base vax_frame_base =
{
- static const unsigned char vax_breakpoint[] = { 3 };
+ &vax_frame_unwind,
+ vax_frame_base_address,
+ vax_frame_base_address,
+ vax_frame_args_address
+};
- *lenptr = sizeof(vax_breakpoint);
- return (vax_breakpoint);
-}
-\f
-/* Advance PC across any function entry prologue instructions
- to reach some "real" code. */
+/* Return number of arguments for FRAME. */
-static CORE_ADDR
-vax_skip_prologue (CORE_ADDR pc)
+static int
+vax_frame_num_args (struct frame_info *frame)
{
- int op = (unsigned char) read_memory_integer (pc, 1);
- if (op == 0x11)
- pc += 2; /* skip brb */
- if (op == 0x31)
- pc += 3; /* skip brw */
- if (op == 0xC2
- && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
- pc += 3; /* skip subl2 */
- if (op == 0x9E
- && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
- && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
- pc += 4; /* skip movab */
- if (op == 0x9E
- && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
- && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
- pc += 5; /* skip movab */
- if (op == 0x9E
- && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
- && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
- pc += 7; /* skip movab */
- return pc;
+ CORE_ADDR args;
+
+ /* Assume that the argument pointer for the outermost frame is
+ hosed, as is the case on NetBSD/vax ELF. */
+ if (get_frame_base_address (frame) == 0)
+ return 0;
+
+ args = get_frame_register_unsigned (frame, VAX_AP_REGNUM);
+ return get_frame_memory_unsigned (frame, args, 1);
}
static CORE_ADDR
-vax_saved_pc_after_call (struct frame_info *frame)
+vax_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
- return (DEPRECATED_FRAME_SAVED_PC(frame));
+ return frame_unwind_register_unsigned (next_frame, VAX_PC_REGNUM);
}
\f
+
/* Initialize the current architecture based on INFO. If possible, re-use an
architecture from ARCHES, which is a list of architectures already created
during this debugging session.
gdbarch = gdbarch_alloc (&info, NULL);
- /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
- ready to unwind the PC first (see frame.c:get_prev_frame()). */
- set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
+ set_gdbarch_float_format (gdbarch, floatformats_vax_f);
+ set_gdbarch_double_format (gdbarch, floatformats_vax_d);
+ set_gdbarch_long_double_format (gdbarch, floatformats_vax_d);
+ set_gdbarch_long_double_bit (gdbarch, 64);
/* Register info */
set_gdbarch_num_regs (gdbarch, VAX_NUM_REGS);
+ set_gdbarch_register_name (gdbarch, vax_register_name);
+ set_gdbarch_register_type (gdbarch, vax_register_type);
set_gdbarch_sp_regnum (gdbarch, VAX_SP_REGNUM);
- set_gdbarch_deprecated_fp_regnum (gdbarch, VAX_FP_REGNUM);
set_gdbarch_pc_regnum (gdbarch, VAX_PC_REGNUM);
set_gdbarch_ps_regnum (gdbarch, VAX_PS_REGNUM);
- set_gdbarch_register_name (gdbarch, vax_register_name);
- set_gdbarch_deprecated_register_size (gdbarch, VAX_REGISTER_SIZE);
- set_gdbarch_deprecated_register_bytes (gdbarch, VAX_REGISTER_BYTES);
- set_gdbarch_deprecated_register_byte (gdbarch, vax_register_byte);
- set_gdbarch_deprecated_register_raw_size (gdbarch, vax_register_raw_size);
- set_gdbarch_deprecated_max_register_raw_size (gdbarch, VAX_MAX_REGISTER_RAW_SIZE);
- set_gdbarch_deprecated_register_virtual_size (gdbarch, vax_register_virtual_size);
- set_gdbarch_deprecated_max_register_virtual_size (gdbarch,
- VAX_MAX_REGISTER_VIRTUAL_SIZE);
- set_gdbarch_deprecated_register_virtual_type (gdbarch, vax_register_virtual_type);
+ set_gdbarch_regset_from_core_section
+ (gdbarch, vax_regset_from_core_section);
/* Frame and stack info */
set_gdbarch_skip_prologue (gdbarch, vax_skip_prologue);
- set_gdbarch_deprecated_saved_pc_after_call (gdbarch, vax_saved_pc_after_call);
-
set_gdbarch_frame_num_args (gdbarch, vax_frame_num_args);
- set_gdbarch_frameless_function_invocation (gdbarch,
- generic_frameless_function_invocation_not);
-
- set_gdbarch_deprecated_frame_chain (gdbarch, vax_frame_chain);
- set_gdbarch_deprecated_frame_saved_pc (gdbarch, vax_frame_saved_pc);
-
- set_gdbarch_deprecated_frame_args_address (gdbarch, vax_frame_args_address);
-
- set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, vax_frame_init_saved_regs);
-
set_gdbarch_frame_args_skip (gdbarch, 4);
+ /* Stack grows downward. */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
/* Return value info */
- set_gdbarch_deprecated_store_struct_return (gdbarch, vax_store_struct_return);
- set_gdbarch_deprecated_extract_return_value (gdbarch, vax_extract_return_value);
- set_gdbarch_deprecated_store_return_value (gdbarch, vax_store_return_value);
- set_gdbarch_deprecated_extract_struct_value_address (gdbarch, vax_extract_struct_value_address);
-
- /* Call dummy info */
- set_gdbarch_deprecated_push_dummy_frame (gdbarch, vax_push_dummy_frame);
- set_gdbarch_deprecated_pop_frame (gdbarch, vax_pop_frame);
- set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
- set_gdbarch_deprecated_call_dummy_words (gdbarch, vax_call_dummy_words);
- set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof_vax_call_dummy_words);
- set_gdbarch_deprecated_fix_call_dummy (gdbarch, vax_fix_call_dummy);
- set_gdbarch_deprecated_call_dummy_breakpoint_offset (gdbarch, 7);
- set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0);
- set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_on_stack);
+ set_gdbarch_return_value (gdbarch, vax_return_value);
+
+ /* Call dummy code. */
+ set_gdbarch_push_dummy_call (gdbarch, vax_push_dummy_call);
+ set_gdbarch_unwind_dummy_id (gdbarch, vax_unwind_dummy_id);
/* Breakpoint info */
set_gdbarch_breakpoint_from_pc (gdbarch, vax_breakpoint_from_pc);
/* Misc info */
- set_gdbarch_function_start_offset (gdbarch, 2);
+ set_gdbarch_deprecated_function_start_offset (gdbarch, 2);
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
- /* Should be using push_dummy_call. */
- set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
+ set_gdbarch_print_insn (gdbarch, print_insn_vax);
+
+ set_gdbarch_unwind_pc (gdbarch, vax_unwind_pc);
+
+ frame_base_set_default (gdbarch, &vax_frame_base);
/* Hook in ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);
- set_gdbarch_print_insn (gdbarch, print_insn_vax);
+ frame_unwind_append_sniffer (gdbarch, vax_frame_sniffer);
return (gdbarch);
}
-extern initialize_file_ftype _initialize_vax_tdep; /* -Wmissing-prototypes */
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_vax_tdep (void);
void
_initialize_vax_tdep (void)