include/opcode/
[deliverable/binutils-gdb.git] / gdb / alpha-tdep.c
index 4b175d015b834f0b742de0d2b6cd3b0f9fd72be6..fe8671f3a5c7497f9b8b0aaa4b8edda1698b0f49 100644 (file)
@@ -1,7 +1,7 @@
 /* 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.
 
@@ -40,6 +40,7 @@
 #include "osabi.h"
 #include "block.h"
 #include "infcall.h"
+#include "trad-frame.h"
 
 #include "elf-bfd.h"
 
@@ -54,7 +55,7 @@
    compatibility with existing remote alpha targets.  */
 
 static const char *
-alpha_register_name (int regno)
+alpha_register_name (struct gdbarch *gdbarch, int regno)
 {
   static const char * const register_names[] =
   {
@@ -77,17 +78,17 @@ alpha_register_name (int regno)
 }
 
 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 (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 (regno)) == 0);
+          || strlen (alpha_register_name (gdbarch, regno)) == 0);
 }
 
 static struct type *
@@ -198,7 +199,7 @@ alpha_sts (void *out, const void *in)
    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);
@@ -563,9 +564,9 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
 }
 
 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);
 
@@ -599,7 +600,7 @@ alpha_return_in_memory_always (struct type *type)
 }
 \f
 static const gdb_byte *
-alpha_breakpoint_from_pc (CORE_ADDR *pc, int *len)
+alpha_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len)
 {
   static const gdb_byte break_insn[] = { 0x80, 0, 0, 0 }; /* call_pal bpt */
 
@@ -637,7 +638,7 @@ alpha_read_insn (CORE_ADDR pc)
   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));
@@ -651,7 +652,7 @@ alpha_read_insn (CORE_ADDR pc)
    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;
@@ -746,7 +747,7 @@ struct alpha_sigtramp_unwind_cache
 };
 
 static struct alpha_sigtramp_unwind_cache *
-alpha_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
+alpha_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
                                   void **this_prologue_cache)
 {
   struct alpha_sigtramp_unwind_cache *info;
@@ -758,8 +759,8 @@ alpha_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
   info = FRAME_OBSTACK_ZALLOC (struct alpha_sigtramp_unwind_cache);
   *this_prologue_cache = info;
 
-  tdep = gdbarch_tdep (get_frame_arch (next_frame));
-  info->sigcontext_addr = tdep->sigcontext_addr (next_frame);
+  tdep = gdbarch_tdep (get_frame_arch (this_frame));
+  info->sigcontext_addr = tdep->sigcontext_addr (this_frame);
 
   return info;
 }
@@ -768,9 +769,10 @@ alpha_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
    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;
@@ -786,13 +788,14 @@ alpha_sigtramp_register_address (CORE_ADDR sigcontext_addr, int regnum)
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-alpha_sigtramp_frame_this_id (struct frame_info *next_frame,
+alpha_sigtramp_frame_this_id (struct frame_info *this_frame,
                              void **this_prologue_cache,
                              struct frame_id *this_id)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_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;
+    = alpha_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache);
   CORE_ADDR stack_addr, code_addr;
 
   /* If the OSABI couldn't locate the sigcontext, give up.  */
@@ -802,11 +805,10 @@ alpha_sigtramp_frame_this_id (struct frame_info *next_frame,
   /* 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_pc_unwind (next_frame);
+      code_addr = get_frame_pc (this_frame);
       offset = tdep->dynamic_sigtramp_offset (code_addr);
       if (offset >= 0)
        code_addr -= offset;
@@ -814,12 +816,12 @@ alpha_sigtramp_frame_this_id (struct frame_info *next_frame,
        code_addr = 0;
     }
   else
-    code_addr = frame_func_unwind (next_frame, SIGTRAMP_FRAME);
+    code_addr = get_frame_func (this_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,
+  stack_addr = get_frame_memory_unsigned (this_frame, stack_addr,
                                          ALPHA_REGISTER_SIZE);
 
   *this_id = frame_id_build (stack_addr, code_addr);
@@ -827,56 +829,37 @@ alpha_sigtramp_frame_this_id (struct frame_info *next_frame,
 
 /* Retrieve the value of REGNUM in FRAME.  Don't give up!  */
 
-static void
-alpha_sigtramp_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 *
+alpha_sigtramp_frame_prev_register (struct frame_info *this_frame,
+                                   void **this_prologue_cache, int regnum)
 {
   struct alpha_sigtramp_unwind_cache *info
-    = alpha_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
+    = alpha_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache);
   CORE_ADDR addr;
 
   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 (this_frame),
+                                             info->sigcontext_addr, regnum);
       if (addr != 0)
-       {
-         *optimizedp = 0;
-         *lvalp = lval_memory;
-         *addrp = addr;
-         *realnump = -1;
-         if (bufferp != NULL)
-           get_frame_memory (next_frame, addr, bufferp, ALPHA_REGISTER_SIZE);
-         return;
-       }
+        return frame_unwind_got_memory (this_frame, regnum, addr);
     }
 
   /* This extra register may actually be in the sigcontext, but our
      current description of it in alpha_sigtramp_frame_unwind_cache
      doesn't include it.  Too bad.  Fall back on whatever's in the
      outer frame.  */
-  *optimizedp = 0;
-  *lvalp = lval_register;
-  *addrp = 0;
-  *realnump = regnum;
-  if (bufferp)
-    frame_unwind_register (next_frame, *realnump, bufferp);
+  return frame_unwind_got_register (this_frame, regnum, regnum);
 }
 
-static const struct frame_unwind alpha_sigtramp_frame_unwind = {
-  SIGTRAMP_FRAME,
-  alpha_sigtramp_frame_this_id,
-  alpha_sigtramp_frame_prev_register
-};
-
-static const struct frame_unwind *
-alpha_sigtramp_frame_sniffer (struct frame_info *next_frame)
+static int
+alpha_sigtramp_frame_sniffer (const struct frame_unwind *self,
+                              struct frame_info *this_frame,
+                              void **this_prologue_cache)
 {
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  CORE_ADDR pc = get_frame_pc (this_frame);
   char *name;
 
   /* NOTE: cagney/2004-04-30: Do not copy/clone this code.  Instead
@@ -886,29 +869,28 @@ alpha_sigtramp_frame_sniffer (struct frame_info *next_frame)
   /* We shouldn't even bother to try if the OSABI didn't register a
      sigcontext_addr handler or pc_in_sigtramp hander.  */
   if (gdbarch_tdep (gdbarch)->sigcontext_addr == NULL)
-    return NULL;
+    return 0;
   if (gdbarch_tdep (gdbarch)->pc_in_sigtramp == NULL)
-    return NULL;
+    return 0;
 
   /* Otherwise we should be in a signal frame.  */
   find_pc_partial_function (pc, &name, NULL, NULL);
   if (gdbarch_tdep (gdbarch)->pc_in_sigtramp (pc, name))
-    return &alpha_sigtramp_frame_unwind;
+    return 1;
 
-  return NULL;
+  return 0;
 }
-\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;
+static const struct frame_unwind alpha_sigtramp_frame_unwind = {
+  SIGTRAMP_FRAME,
+  alpha_sigtramp_frame_this_id,
+  alpha_sigtramp_frame_prev_register,
+  NULL,
+  alpha_sigtramp_frame_sniffer
 };
 
+\f
+
 /* 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
    search.  */
@@ -920,9 +902,9 @@ static unsigned int heuristic_fence_post = 0;
    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;
@@ -994,11 +976,23 @@ Otherwise, you told GDB there was a function where there isn't one, or\n\
   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,
+alpha_heuristic_frame_unwind_cache (struct frame_info *this_frame,
                                    void **this_prologue_cache,
                                    CORE_ADDR start_pc)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct alpha_heuristic_unwind_cache *info;
   ULONGEST val;
   CORE_ADDR limit_pc, cur_pc;
@@ -1009,11 +1003,11 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
 
   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 (this_frame);
 
-  limit_pc = frame_pc_unwind (next_frame);
+  limit_pc = get_frame_pc (this_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;
@@ -1059,7 +1053,7 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
                  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)
@@ -1075,7 +1069,7 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
                 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
@@ -1146,14 +1140,19 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
     return_reg = ALPHA_RA_REGNUM;
   info->return_reg = return_reg;
 
-  val = frame_unwind_register_unsigned (next_frame, frame_reg);
+  val = get_frame_register_unsigned (this_frame, frame_reg);
   info->vfp = val + frame_size;
 
   /* 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;
+
+  /* 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, info->vfp);
 
   return info;
 }
@@ -1162,27 +1161,24 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-alpha_heuristic_frame_this_id (struct frame_info *next_frame,
-                                void **this_prologue_cache,
-                                struct frame_id *this_id)
+alpha_heuristic_frame_this_id (struct frame_info *this_frame,
+                              void **this_prologue_cache,
+                              struct frame_id *this_id)
 {
   struct alpha_heuristic_unwind_cache *info
-    = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0);
+    = alpha_heuristic_frame_unwind_cache (this_frame, this_prologue_cache, 0);
 
   *this_id = frame_id_build (info->vfp, info->start_pc);
 }
 
 /* Retrieve the value of REGNUM in FRAME.  Don't give up!  */
 
-static void
-alpha_heuristic_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 *
+alpha_heuristic_frame_prev_register (struct frame_info *this_frame,
+                                    void **this_prologue_cache, int regnum)
 {
   struct alpha_heuristic_unwind_cache *info
-    = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0);
+    = alpha_heuristic_frame_unwind_cache (this_frame, this_prologue_cache, 0);
 
   /* The PC of the previous frame is stored in the link register of
      the current frame.  Frob regnum so that we pull the value from
@@ -1190,59 +1186,23 @@ alpha_heuristic_frame_prev_register (struct frame_info *next_frame,
   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);
+  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
 }
 
 static const struct frame_unwind alpha_heuristic_frame_unwind = {
   NORMAL_FRAME,
   alpha_heuristic_frame_this_id,
-  alpha_heuristic_frame_prev_register
+  alpha_heuristic_frame_prev_register,
+  NULL,
+  default_frame_sniffer
 };
 
-static const struct frame_unwind *
-alpha_heuristic_frame_sniffer (struct frame_info *next_frame)
-{
-  return &alpha_heuristic_frame_unwind;
-}
-
 static CORE_ADDR
-alpha_heuristic_frame_base_address (struct frame_info *next_frame,
+alpha_heuristic_frame_base_address (struct frame_info *this_frame,
                                    void **this_prologue_cache)
 {
   struct alpha_heuristic_unwind_cache *info
-    = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0);
+    = alpha_heuristic_frame_unwind_cache (this_frame, this_prologue_cache, 0);
 
   return info->vfp;
 }
@@ -1270,11 +1230,11 @@ reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c)
    breakpoint.  */
 
 static struct frame_id
-alpha_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+alpha_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
   ULONGEST base;
-  base = frame_unwind_register_unsigned (next_frame, ALPHA_SP_REGNUM);
-  return frame_id_build (base, frame_pc_unwind (next_frame));
+  base = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
+  return frame_id_build (base, get_frame_pc (this_frame));
 }
 
 static CORE_ADDR
@@ -1609,7 +1569,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_push_dummy_call (gdbarch, alpha_push_dummy_call);
 
   /* Methods for saving / extracting a dummy frame's ID.  */
-  set_gdbarch_unwind_dummy_id (gdbarch, alpha_unwind_dummy_id);
+  set_gdbarch_dummy_id (gdbarch, alpha_dummy_id);
 
   /* Return the unwound PC value.  */
   set_gdbarch_unwind_pc (gdbarch, alpha_unwind_pc);
@@ -1630,8 +1590,8 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (tdep->jb_pc >= 0)
     set_gdbarch_get_longjmp_target (gdbarch, alpha_get_longjmp_target);
 
-  frame_unwind_append_sniffer (gdbarch, alpha_sigtramp_frame_sniffer);
-  frame_unwind_append_sniffer (gdbarch, alpha_heuristic_frame_sniffer);
+  frame_unwind_append_unwinder (gdbarch, &alpha_sigtramp_frame_unwind);
+  frame_unwind_append_unwinder (gdbarch, &alpha_heuristic_frame_unwind);
 
   frame_base_set_default (gdbarch, &alpha_heuristic_frame_base);
 
@@ -1641,7 +1601,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 void
 alpha_dwarf2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
-  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+  dwarf2_append_unwinders (gdbarch);
   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
 }
 
This page took 0.032649 seconds and 4 git commands to generate.