/* Target-dependent mdebug code for the ALPHA architecture.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1993-2015 Free Software Foundation, Inc.
This file is part of GDB.
#include "symtab.h"
#include "gdbcore.h"
#include "block.h"
-#include "gdb_assert.h"
-#include "gdb_string.h"
+#include "trad-frame.h"
#include "alpha-tdep.h"
#include "mdebugread.h"
static struct mdebug_extra_func_info *
find_proc_desc (CORE_ADDR pc)
{
- struct block *b = block_for_pc (pc);
+ const struct block *b = block_for_pc (pc);
struct mdebug_extra_func_info *proc_desc = NULL;
struct symbol *sym = NULL;
- char *sh_name = NULL;
+ const char *sh_name = NULL;
if (b)
{
symbol reading. */
sym = NULL;
else
- sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0, NULL);
+ sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN,
+ 0).symbol;
}
if (sym)
{
- proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE (sym);
+ proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE_BYTES (sym);
/* Correct incorrect setjmp procedure descriptor from the library
to make backtrace through setjmp work. */
return proc_desc;
}
+/* Return a non-zero result if the function is frameless; zero otherwise. */
+
+static int
+alpha_mdebug_frameless (struct mdebug_extra_func_info *proc_desc)
+{
+ return (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM
+ && PROC_FRAME_OFFSET (proc_desc) == 0);
+}
+
/* This returns the PC of the first inst after the prologue. If we can't
find the prologue, then return 0. */
static CORE_ADDR
-alpha_mdebug_after_prologue (CORE_ADDR pc, struct mdebug_extra_func_info *proc_desc)
+alpha_mdebug_after_prologue (CORE_ADDR pc,
+ struct mdebug_extra_func_info *proc_desc)
{
if (proc_desc)
{
/* If function is frameless, then we need to do it the hard way. I
- strongly suspect that frameless always means prologueless... */
- if (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM
- && PROC_FRAME_OFFSET (proc_desc) == 0)
+ strongly suspect that frameless always means prologueless... */
+ if (alpha_mdebug_frameless (proc_desc))
return 0;
}
if we are definitively *not* in a function prologue. */
static int
-alpha_mdebug_in_prologue (CORE_ADDR pc, struct mdebug_extra_func_info *proc_desc)
+alpha_mdebug_in_prologue (CORE_ADDR pc,
+ struct mdebug_extra_func_info *proc_desc)
{
CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc);
return (after_prologue_pc == 0 || pc < after_prologue_pc);
{
struct mdebug_extra_func_info *proc_desc;
CORE_ADDR vfp;
- CORE_ADDR *saved_regs;
+ struct trad_frame_saved_reg *saved_regs;
};
/* Extract all of the information about the frame from PROC_DESC
info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache);
*this_prologue_cache = info;
- pc = get_frame_pc (this_frame);
+ pc = get_frame_address_in_block (this_frame);
/* ??? We don't seem to be able to cache the lookup of the PDR
from alpha_mdebug_frame_p. It'd be nice if we could change
info->proc_desc = proc_desc;
gdb_assert (proc_desc != NULL);
- info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS);
+ info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
/* The VFP of the frame is at FRAME_REG+FRAME_OFFSET. */
vfp = get_frame_register_unsigned (this_frame, PROC_FRAME_REG (proc_desc));
register number. */
if (mask & (1 << returnreg))
{
- /* Clear bit for RA so we don't save it again later. */
+ /* Clear bit for RA so we don't save it again later. */
mask &= ~(1 << returnreg);
- info->saved_regs[returnreg] = reg_position;
+ info->saved_regs[returnreg].addr = reg_position;
reg_position += 8;
}
for (ireg = 0; ireg <= 31; ++ireg)
if (mask & (1 << ireg))
{
- info->saved_regs[ireg] = reg_position;
+ info->saved_regs[ireg].addr = reg_position;
reg_position += 8;
}
for (ireg = 0; ireg <= 31; ++ireg)
if (mask & (1 << ireg))
{
- info->saved_regs[ALPHA_FP0_REGNUM + ireg] = reg_position;
+ info->saved_regs[ALPHA_FP0_REGNUM + ireg].addr = reg_position;
reg_position += 8;
}
+ /* The stack pointer of the previous frame is computed by popping
+ the current stack frame. */
+ if (!trad_frame_addr_p (info->saved_regs, ALPHA_SP_REGNUM))
+ trad_frame_set_value (info->saved_regs, ALPHA_SP_REGNUM, vfp);
+
return info;
}
if (regnum == ALPHA_PC_REGNUM)
regnum = PROC_PC_REG (info->proc_desc);
- /* For all registers known to be saved in the current frame,
- do the obvious and pull the value out. */
- if (info->saved_regs[regnum])
- return frame_unwind_got_memory (this_frame, regnum,
- info->saved_regs[regnum]);
+ return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
+}
- /* The stack pointer of the previous frame is computed by popping
- the current stack frame. */
- if (regnum == ALPHA_SP_REGNUM)
- return frame_unwind_got_constant (this_frame, regnum, info->vfp);
+/* Return a non-zero result if the size of the stack frame exceeds the
+ maximum debuggable frame size (512 Kbytes); zero otherwise. */
+
+static int
+alpha_mdebug_max_frame_size_exceeded (struct mdebug_extra_func_info *proc_desc)
+{
+ /* If frame offset is null, we can be in two cases: either the
+ function is frameless (the stack frame is null) or its
+ frame exceeds the maximum debuggable frame size (512 Kbytes). */
- /* Otherwise assume the next frame has the same register value. */
- return frame_unwind_got_register (this_frame, regnum, regnum);
+ return (PROC_FRAME_OFFSET (proc_desc) == 0
+ && !alpha_mdebug_frameless (proc_desc));
}
static int
if (alpha_mdebug_in_prologue (pc, proc_desc))
return 0;
+ /* If the maximum debuggable frame size has been exceeded, the
+ proc desc is bogus. Fall back on the heuristic unwinder. */
+ if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
+ return 0;
+
return 1;
}
static const struct frame_unwind alpha_mdebug_frame_unwind = {
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
alpha_mdebug_frame_this_id,
alpha_mdebug_frame_prev_register,
NULL,
if (proc_desc == NULL)
return NULL;
+ /* If the maximum debuggable frame size has been exceeded, the
+ proc desc is bogus. Fall back on the heuristic unwinder. */
+ if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
+ return 0;
+
return &alpha_mdebug_frame_base;
}