/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GDB.
#include "osabi.h"
#include "block.h"
#include "infcall.h"
+#include "trad-frame.h"
#include "elf-bfd.h"
}
static int
-alpha_cannot_fetch_register (int regno)
+alpha_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
{
return (regno == ALPHA_ZERO_REGNUM
- || strlen (alpha_register_name (current_gdbarch, regno)) == 0);
+ || strlen (alpha_register_name (gdbarch, regno)) == 0);
}
static int
-alpha_cannot_store_register (int regno)
+alpha_cannot_store_register (struct gdbarch *gdbarch, int regno)
{
return (regno == ALPHA_ZERO_REGNUM
- || strlen (alpha_register_name (current_gdbarch, regno)) == 0);
+ || strlen (alpha_register_name (gdbarch, regno)) == 0);
}
static struct type *
registers is different. */
static int
-alpha_convert_register_p (int regno, struct type *type)
+alpha_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type)
{
return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31
&& TYPE_LENGTH (type) != 8);
}
static enum return_value_convention
-alpha_return_value (struct gdbarch *gdbarch, struct type *type,
- struct regcache *regcache, gdb_byte *readbuf,
- const gdb_byte *writebuf)
+alpha_return_value (struct gdbarch *gdbarch, struct type *func_type,
+ struct type *type, struct regcache *regcache,
+ gdb_byte *readbuf, const gdb_byte *writebuf)
{
enum type_code code = TYPE_CODE (type);
gdb_byte buf[ALPHA_INSN_SIZE];
int status;
- status = read_memory_nobpt (pc, buf, sizeof (buf));
+ status = target_read_memory (pc, buf, sizeof (buf));
if (status)
memory_error (status, pc);
return extract_unsigned_integer (buf, sizeof (buf));
anything which might clobber the registers which are being saved. */
static CORE_ADDR
-alpha_skip_prologue (CORE_ADDR pc)
+alpha_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
unsigned long inst;
int offset;
all arithmetic, it doesn't seem worthwhile to cache it. */
static CORE_ADDR
-alpha_sigtramp_register_address (CORE_ADDR sigcontext_addr, int regnum)
+alpha_sigtramp_register_address (struct gdbarch *gdbarch,
+ CORE_ADDR sigcontext_addr, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (regnum >= 0 && regnum < 32)
return sigcontext_addr + tdep->sc_regs_offset + regnum * 8;
void **this_prologue_cache,
struct frame_id *this_id)
{
+ struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct alpha_sigtramp_unwind_cache *info
= alpha_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
- struct gdbarch_tdep *tdep;
CORE_ADDR stack_addr, code_addr;
/* If the OSABI couldn't locate the sigcontext, give up. */
/* If we have dynamic signal trampolines, find their start.
If we do not, then we must assume there is a symbol record
that can provide the start address. */
- tdep = gdbarch_tdep (get_frame_arch (next_frame));
if (tdep->dynamic_sigtramp_offset)
{
int offset;
code_addr = frame_func_unwind (next_frame, SIGTRAMP_FRAME);
/* The stack address is trivially read from the sigcontext. */
- stack_addr = alpha_sigtramp_register_address (info->sigcontext_addr,
+ stack_addr = alpha_sigtramp_register_address (gdbarch, info->sigcontext_addr,
ALPHA_SP_REGNUM);
stack_addr = get_frame_memory_unsigned (next_frame, stack_addr,
ALPHA_REGISTER_SIZE);
if (info->sigcontext_addr != 0)
{
/* All integer and fp registers are stored in memory. */
- addr = alpha_sigtramp_register_address (info->sigcontext_addr, regnum);
+ addr = alpha_sigtramp_register_address (get_frame_arch (next_frame),
+ info->sigcontext_addr, regnum);
if (addr != 0)
{
*optimizedp = 0;
return NULL;
}
\f
-/* Fallback alpha frame unwinder. Uses instruction scanning and knows
- something about the traditional layout of alpha stack frames. */
-
-struct alpha_heuristic_unwind_cache
-{
- CORE_ADDR *saved_regs;
- CORE_ADDR vfp;
- CORE_ADDR start_pc;
- int return_reg;
-};
/* Heuristic_proc_start may hunt through the text section for a long
time across a 2400 baud serial line. Allows the user to limit this
function. But we're guessing anyway... */
static CORE_ADDR
-alpha_heuristic_proc_start (CORE_ADDR pc)
+alpha_heuristic_proc_start (struct gdbarch *gdbarch, CORE_ADDR pc)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
CORE_ADDR last_non_nop = pc;
CORE_ADDR fence = pc - heuristic_fence_post;
CORE_ADDR orig_pc = pc;
return 0;
}
+/* Fallback alpha frame unwinder. Uses instruction scanning and knows
+ something about the traditional layout of alpha stack frames. */
+
+struct alpha_heuristic_unwind_cache
+{
+ CORE_ADDR vfp;
+ CORE_ADDR start_pc;
+ struct trad_frame_saved_reg *saved_regs;
+ int return_reg;
+};
+
static struct alpha_heuristic_unwind_cache *
alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
void **this_prologue_cache,
CORE_ADDR start_pc)
{
+ struct gdbarch *gdbarch = get_frame_arch (next_frame);
struct alpha_heuristic_unwind_cache *info;
ULONGEST val;
CORE_ADDR limit_pc, cur_pc;
info = FRAME_OBSTACK_ZALLOC (struct alpha_heuristic_unwind_cache);
*this_prologue_cache = info;
- info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS);
+ info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
limit_pc = frame_pc_unwind (next_frame);
if (start_pc == 0)
- start_pc = alpha_heuristic_proc_start (limit_pc);
+ start_pc = alpha_heuristic_proc_start (gdbarch, limit_pc);
info->start_pc = start_pc;
frame_reg = ALPHA_SP_REGNUM;
All it says is that the function we are scanning reused
that register for some computation of its own, and is now
saving its result. */
- if (info->saved_regs[reg])
+ if (trad_frame_addr_p(info->saved_regs, reg))
continue;
if (reg == 31)
pointer or not. */
/* Hack: temporarily add one, so that the offset is non-zero
and we can tell which registers have save offsets below. */
- info->saved_regs[reg] = (word & 0xffff) + 1;
+ info->saved_regs[reg].addr = (word & 0xffff) + 1;
/* Starting with OSF/1-3.2C, the system libraries are shipped
without local symbols, but they still contain procedure
/* Convert offsets to absolute addresses. See above about adding
one to the offsets to make all detected offsets non-zero. */
for (reg = 0; reg < ALPHA_NUM_REGS; ++reg)
- if (info->saved_regs[reg])
- info->saved_regs[reg] += val - 1;
+ if (trad_frame_addr_p(info->saved_regs, reg))
+ info->saved_regs[reg].addr += val - 1;
return info;
}
if (regnum == ALPHA_PC_REGNUM)
regnum = info->return_reg;
- /* For all registers known to be saved in the current frame,
- do the obvious and pull the value out. */
- if (info->saved_regs[regnum])
- {
- *optimizedp = 0;
- *lvalp = lval_memory;
- *addrp = info->saved_regs[regnum];
- *realnump = -1;
- if (bufferp != NULL)
- get_frame_memory (next_frame, *addrp, bufferp, ALPHA_REGISTER_SIZE);
- return;
- }
-
- /* The stack pointer of the previous frame is computed by popping
- the current stack frame. */
- if (regnum == ALPHA_SP_REGNUM)
- {
- *optimizedp = 0;
- *lvalp = not_lval;
- *addrp = 0;
- *realnump = -1;
- if (bufferp != NULL)
- store_unsigned_integer (bufferp, ALPHA_REGISTER_SIZE, info->vfp);
- return;
- }
-
- /* Otherwise assume the next frame has the same register value. */
- *optimizedp = 0;
- *lvalp = lval_register;
- *addrp = 0;
- *realnump = regnum;
- if (bufferp)
- frame_unwind_register (next_frame, *realnump, bufferp);
+ trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
+ optimizedp, lvalp, addrp, realnump, bufferp);
}
static const struct frame_unwind alpha_heuristic_frame_unwind = {