daily update
[deliverable/binutils-gdb.git] / gdb / sparc-tdep.c
index a55687f03fc2d94f3648e8cc88f864761c327b91..898e96f835e7f91bd82211b6a32684da0d8acb71 100644 (file)
@@ -1,12 +1,13 @@
 /* Target-dependent code for SPARC.
 
-   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 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,
@@ -15,9 +16,7 @@
    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/>.  */
 
 #include "defs.h"
 #include "arch-utils.h"
@@ -82,6 +81,7 @@ struct regset;
 #define X_IMM22(i) ((i) & 0x3fffff)
 #define X_OP3(i) (((i) >> 19) & 0x3f)
 #define X_RS1(i) (((i) >> 14) & 0x1f)
+#define X_RS2(i) ((i) & 0x1f)
 #define X_I(i) (((i) >> 13) & 1)
 /* Sign extension macros.  */
 #define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000)
@@ -99,7 +99,7 @@ sparc_fetch_instruction (CORE_ADDR pc)
   int i;
 
   /* If we can't read the instruction at PC, return zero.  */
-  if (read_memory_nobpt (pc, buf, sizeof (buf)))
+  if (target_read_memory (pc, buf, sizeof (buf)))
     return 0;
 
   insn = 0;
@@ -169,18 +169,6 @@ sparc_fetch_wcookie (void)
 }
 \f
 
-/* Return the contents if register REGNUM as an address.  */
-
-CORE_ADDR
-sparc_address_from_register (int regnum)
-{
-  ULONGEST addr;
-
-  regcache_cooked_read_unsigned (current_regcache, regnum, &addr);
-  return addr;
-}
-\f
-
 /* The functions on this page are intended to be used to classify
    function arguments.  */
 
@@ -284,7 +272,7 @@ static const char *sparc32_pseudo_register_names[] =
 /* Return the name of register REGNUM.  */
 
 static const char *
-sparc32_register_name (int regnum)
+sparc32_register_name (struct gdbarch *gdbarch, int regnum)
 {
   if (regnum >= 0 && regnum < SPARC32_NUM_REGS)
     return sparc32_register_names[regnum];
@@ -391,15 +379,16 @@ sparc32_pseudo_register_write (struct gdbarch *gdbarch,
 
 static CORE_ADDR
 sparc32_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
-                        CORE_ADDR funcaddr, int using_gcc,
+                        CORE_ADDR funcaddr,
                         struct value **args, int nargs,
                         struct type *value_type,
-                        CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
+                        CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
+                        struct regcache *regcache)
 {
   *bp_addr = sp - 4;
   *real_pc = funcaddr;
 
-  if (using_struct_return (value_type, using_gcc))
+  if (using_struct_return (NULL, value_type))
     {
       gdb_byte buf[4];
 
@@ -540,7 +529,7 @@ sparc32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
    location for inserting the breakpoint.  */
    
 static const gdb_byte *
-sparc_breakpoint_from_pc (CORE_ADDR *pc, int *len)
+sparc_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len)
 {
   static const gdb_byte break_insn[] = { 0x91, 0xd0, 0x20, 0x01 };
 
@@ -571,15 +560,167 @@ sparc_alloc_frame_cache (void)
   return cache;
 }
 
+/* GCC generates several well-known sequences of instructions at the begining
+   of each function prologue when compiling with -fstack-check.  If one of
+   such sequences starts at START_PC, then return the address of the
+   instruction immediately past this sequence.  Otherwise, return START_PC.  */
+   
+static CORE_ADDR
+sparc_skip_stack_check (const CORE_ADDR start_pc)
+{
+  CORE_ADDR pc = start_pc;
+  unsigned long insn;
+  int offset_stack_checking_sequence = 0;
+
+  /* With GCC, all stack checking sequences begin with the same two
+     instructions.  */
+
+  /* sethi <some immediate>,%g1 */
+  insn = sparc_fetch_instruction (pc);
+  pc = pc + 4;
+  if (!(X_OP (insn) == 0 && X_OP2 (insn) == 0x4 && X_RD (insn) == 1))
+    return start_pc;
+
+  /* sub %sp, %g1, %g1 */
+  insn = sparc_fetch_instruction (pc);
+  pc = pc + 4;
+  if (!(X_OP (insn) == 2 && X_OP3 (insn) == 0x4 && !X_I(insn)
+        && X_RD (insn) == 1 && X_RS1 (insn) == 14 && X_RS2 (insn) == 1))
+    return start_pc;
+
+  insn = sparc_fetch_instruction (pc);
+  pc = pc + 4;
+
+  /* First possible sequence:
+         [first two instructions above]
+         clr [%g1 - some immediate]  */
+
+  /* clr [%g1 - some immediate]  */
+  if (X_OP (insn) == 3 && X_OP3(insn) == 0x4 && X_I(insn)
+      && X_RS1 (insn) == 1 && X_RD (insn) == 0)
+    {
+      /* Valid stack-check sequence, return the new PC.  */
+      return pc;
+    }
+
+  /* Second possible sequence: A small number of probes.
+         [first two instructions above]
+         clr [%g1]
+         add   %g1, -<some immediate>, %g1
+         clr [%g1]
+         [repeat the two instructions above any (small) number of times]
+         clr [%g1 - some immediate]  */
+
+  /* clr [%g1] */
+  else if (X_OP (insn) == 3 && X_OP3(insn) == 0x4 && !X_I(insn)
+      && X_RS1 (insn) == 1 && X_RD (insn) == 0)
+    {
+      while (1)
+        {
+          /* add %g1, -<some immediate>, %g1 */
+          insn = sparc_fetch_instruction (pc);
+          pc = pc + 4;
+          if (!(X_OP (insn) == 2  && X_OP3(insn) == 0 && X_I(insn)
+                && X_RS1 (insn) == 1 && X_RD (insn) == 1))
+            break;
+
+          /* clr [%g1] */
+          insn = sparc_fetch_instruction (pc);
+          pc = pc + 4;
+          if (!(X_OP (insn) == 3 && X_OP3(insn) == 0x4 && !X_I(insn)
+                && X_RD (insn) == 0 && X_RS1 (insn) == 1))
+            return start_pc;
+        }
+
+      /* clr [%g1 - some immediate] */
+      if (!(X_OP (insn) == 3 && X_OP3(insn) == 0x4 && X_I(insn)
+            && X_RS1 (insn) == 1 && X_RD (insn) == 0))
+        return start_pc;
+
+      /* We found a valid stack-check sequence, return the new PC.  */
+      return pc;
+    }
+  
+  /* Third sequence: A probing loop.
+         [first two instructions above]
+         sethi  <some immediate>, %g4
+         sub  %g1, %g4, %g4
+         cmp  %g1, %g4
+         be  <disp>
+         add  %g1, -<some immediate>, %g1
+         ba  <disp>
+         clr  [%g1]
+         clr [%g4 - some immediate]  */
+
+  /* sethi  <some immediate>, %g4 */
+  else if (X_OP (insn) == 0 && X_OP2 (insn) == 0x4 && X_RD (insn) == 4)
+    {
+      /* sub  %g1, %g4, %g4 */
+      insn = sparc_fetch_instruction (pc);
+      pc = pc + 4;
+      if (!(X_OP (insn) == 2 && X_OP3 (insn) == 0x4 && !X_I(insn)
+            && X_RD (insn) == 4 && X_RS1 (insn) == 1 && X_RS2 (insn) == 4))
+        return start_pc;
+
+      /* cmp  %g1, %g4 */
+      insn = sparc_fetch_instruction (pc);
+      pc = pc + 4;
+      if (!(X_OP (insn) == 2 && X_OP3 (insn) == 0x14 && !X_I(insn)
+            && X_RD (insn) == 0 && X_RS1 (insn) == 1 && X_RS2 (insn) == 4))
+        return start_pc;
+
+      /* be  <disp> */
+      insn = sparc_fetch_instruction (pc);
+      pc = pc + 4;
+      if (!(X_OP (insn) == 0 && X_COND (insn) == 0x1))
+        return start_pc;
+
+      /* add  %g1, -<some immediate>, %g1 */
+      insn = sparc_fetch_instruction (pc);
+      pc = pc + 4;
+      if (!(X_OP (insn) == 2  && X_OP3(insn) == 0 && X_I(insn)
+            && X_RS1 (insn) == 1 && X_RD (insn) == 1))
+        return start_pc;
+
+      /* ba  <disp> */
+      insn = sparc_fetch_instruction (pc);
+      pc = pc + 4;
+      if (!(X_OP (insn) == 0 && X_COND (insn) == 0x8))
+        return start_pc;
+
+      /* clr  [%g1] */
+      insn = sparc_fetch_instruction (pc);
+      pc = pc + 4;
+      if (!(X_OP (insn) == 3 && X_OP3(insn) == 0x4 && !X_I(insn)
+            && X_RD (insn) == 0 && X_RS1 (insn) == 1))
+        return start_pc;
+
+      /* clr [%g4 - some immediate]  */
+      insn = sparc_fetch_instruction (pc);
+      pc = pc + 4;
+      if (!(X_OP (insn) == 3 && X_OP3(insn) == 0x4 && X_I(insn)
+            && X_RS1 (insn) == 4 && X_RD (insn) == 0))
+        return start_pc;
+
+      /* We found a valid stack-check sequence, return the new PC.  */
+      return pc;
+    }
+
+  /* No stack check code in our prologue, return the start_pc.  */
+  return start_pc;
+}
+
 CORE_ADDR
-sparc_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
-                       struct sparc_frame_cache *cache)
+sparc_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
+                       CORE_ADDR current_pc, struct sparc_frame_cache *cache)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   unsigned long insn;
   int offset = 0;
   int dest = -1;
 
+  pc = sparc_skip_stack_check (pc);
+
   if (current_pc <= pc)
     return current_pc;
 
@@ -627,17 +768,17 @@ sparc_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
 }
 
 static CORE_ADDR
-sparc_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+sparc_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  return frame_unwind_register_unsigned (next_frame, tdep->pc_regnum);
+  return frame_unwind_register_unsigned (this_frame, tdep->pc_regnum);
 }
 
 /* Return PC of first real instruction of the function starting at
    START_PC.  */
 
 static CORE_ADDR
-sparc32_skip_prologue (CORE_ADDR start_pc)
+sparc32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 {
   struct symtab_and_line sal;
   CORE_ADDR func_start, func_end;
@@ -654,7 +795,7 @@ sparc32_skip_prologue (CORE_ADDR start_pc)
        return sal.end;
     }
 
-  start_pc = sparc_analyze_prologue (start_pc, 0xffffffffUL, &cache);
+  start_pc = sparc_analyze_prologue (gdbarch, start_pc, 0xffffffffUL, &cache);
 
   /* The psABI says that "Although the first 6 words of arguments
      reside in registers, the standard stack frame reserves space for
@@ -689,7 +830,7 @@ sparc32_skip_prologue (CORE_ADDR start_pc)
 /* Normal frames.  */
 
 struct sparc_frame_cache *
-sparc_frame_cache (struct frame_info *next_frame, void **this_cache)
+sparc_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   struct sparc_frame_cache *cache;
 
@@ -699,12 +840,10 @@ sparc_frame_cache (struct frame_info *next_frame, void **this_cache)
   cache = sparc_alloc_frame_cache ();
   *this_cache = cache;
 
-  cache->pc = frame_func_unwind (next_frame);
+  cache->pc = get_frame_func (this_frame);
   if (cache->pc != 0)
-    {
-      CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame);
-      sparc_analyze_prologue (cache->pc, addr_in_block, cache);
-    }
+    sparc_analyze_prologue (get_frame_arch (this_frame), cache->pc,
+                           get_frame_pc (this_frame), cache);
 
   if (cache->frameless_p)
     {
@@ -712,14 +851,14 @@ sparc_frame_cache (struct frame_info *next_frame, void **this_cache)
          pointer for our calling frame.  Use %sp (%o6) as this frame's
          base address.  */
       cache->base =
-       frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
+        get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
     }
   else
     {
       /* For normal frames, %fp (%i6) holds the frame pointer, the
          base address for the current stack frame.  */
       cache->base =
-       frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM);
+       get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
     }
 
   if (cache->base & 1)
@@ -746,7 +885,7 @@ sparc32_struct_return_from_sym (struct symbol *sym)
 }
 
 struct sparc_frame_cache *
-sparc32_frame_cache (struct frame_info *next_frame, void **this_cache)
+sparc32_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   struct sparc_frame_cache *cache;
   struct symbol *sym;
@@ -754,7 +893,7 @@ sparc32_frame_cache (struct frame_info *next_frame, void **this_cache)
   if (*this_cache)
     return *this_cache;
 
-  cache = sparc_frame_cache (next_frame, this_cache);
+  cache = sparc_frame_cache (this_frame, this_cache);
 
   sym = find_pc_function (cache->pc);
   if (sym)
@@ -772,7 +911,7 @@ sparc32_frame_cache (struct frame_info *next_frame, void **this_cache)
       CORE_ADDR pc;
       int regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM;
 
-      pc = frame_unwind_register_unsigned (next_frame, regnum) + 8;
+      pc = get_frame_register_unsigned (this_frame, regnum) + 8;
       if (sparc_is_unimp_insn (pc))
         cache->struct_return_p = 1;
     }
@@ -781,11 +920,11 @@ sparc32_frame_cache (struct frame_info *next_frame, void **this_cache)
 }
 
 static void
-sparc32_frame_this_id (struct frame_info *next_frame, void **this_cache,
+sparc32_frame_this_id (struct frame_info *this_frame, void **this_cache,
                       struct frame_id *this_id)
 {
   struct sparc_frame_cache *cache =
-    sparc32_frame_cache (next_frame, this_cache);
+    sparc32_frame_cache (this_frame, this_cache);
 
   /* This marks the outermost frame.  */
   if (cache->base == 0)
@@ -794,36 +933,26 @@ sparc32_frame_this_id (struct frame_info *next_frame, void **this_cache,
   (*this_id) = frame_id_build (cache->base, cache->pc);
 }
 
-static void
-sparc32_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)
+static struct value *
+sparc32_frame_prev_register (struct frame_info *this_frame,
+                            void **this_cache, int regnum)
 {
   struct sparc_frame_cache *cache =
-    sparc32_frame_cache (next_frame, this_cache);
+    sparc32_frame_cache (this_frame, this_cache);
 
   if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
     {
-      *optimizedp = 0;
-      *lvalp = not_lval;
-      *addrp = 0;
-      *realnump = -1;
-      if (valuep)
-       {
-         CORE_ADDR pc = (regnum == SPARC32_NPC_REGNUM) ? 4 : 0;
+      CORE_ADDR pc = (regnum == SPARC32_NPC_REGNUM) ? 4 : 0;
 
-         /* If this functions has a Structure, Union or
-             Quad-Precision return value, we have to skip the UNIMP
-             instruction that encodes the size of the structure.  */
-         if (cache->struct_return_p)
-           pc += 4;
+      /* If this functions has a Structure, Union or Quad-Precision
+        return value, we have to skip the UNIMP instruction that encodes
+        the size of the structure.  */
+      if (cache->struct_return_p)
+       pc += 4;
 
-         regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM;
-         pc += frame_unwind_register_unsigned (next_frame, regnum) + 8;
-         store_unsigned_integer (valuep, 4, pc);
-       }
-      return;
+      regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM;
+      pc += get_frame_register_unsigned (this_frame, regnum) + 8;
+      return frame_unwind_got_constant (this_frame, regnum, pc);
     }
 
   /* Handle StackGhost.  */
@@ -832,20 +961,12 @@ sparc32_frame_prev_register (struct frame_info *next_frame, void **this_cache,
 
     if (wcookie != 0 && !cache->frameless_p && regnum == SPARC_I7_REGNUM)
       {
-       *optimizedp = 0;
-       *lvalp = not_lval;
-       *addrp = 0;
-       *realnump = -1;
-       if (valuep)
-         {
-           CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
-           ULONGEST i7;
-
-           /* Read the value in from memory.  */
-           i7 = get_frame_memory_unsigned (next_frame, addr, 4);
-           store_unsigned_integer (valuep, 4, i7 ^ wcookie);
-         }
-       return;
+        CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
+        ULONGEST i7;
+
+        /* Read the value in from memory.  */
+        i7 = get_frame_memory_unsigned (this_frame, addr, 4);
+        return frame_unwind_got_constant (this_frame, regnum, i7 ^ wcookie);
       }
   }
 
@@ -854,53 +975,35 @@ sparc32_frame_prev_register (struct frame_info *next_frame, void **this_cache,
   if (!cache->frameless_p
       && regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)
     {
-      *optimizedp = 0;
-      *lvalp = lval_memory;
-      *addrp = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
-      *realnump = -1;
-      if (valuep)
-       {
-         struct gdbarch *gdbarch = get_frame_arch (next_frame);
+      CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
 
-         /* Read the value in from memory.  */
-         read_memory (*addrp, valuep, register_size (gdbarch, regnum));
-       }
-      return;
+      return frame_unwind_got_memory (this_frame, regnum, addr);
     }
 
-  /* The previous frame's `out' registers are accessable as the
+  /* The previous frame's `out' registers are accessible as the
      current frame's `in' registers.  */
   if (!cache->frameless_p
       && regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
     regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
 
-  *optimizedp = 0;
-  *lvalp = lval_register;
-  *addrp = 0;
-  *realnump = regnum;
-  if (valuep)
-    frame_unwind_register (next_frame, (*realnump), valuep);
+  return frame_unwind_got_register (this_frame, regnum, regnum);
 }
 
 static const struct frame_unwind sparc32_frame_unwind =
 {
   NORMAL_FRAME,
   sparc32_frame_this_id,
-  sparc32_frame_prev_register
+  sparc32_frame_prev_register,
+  NULL,
+  default_frame_sniffer
 };
-
-static const struct frame_unwind *
-sparc32_frame_sniffer (struct frame_info *next_frame)
-{
-  return &sparc32_frame_unwind;
-}
 \f
 
 static CORE_ADDR
-sparc32_frame_base_address (struct frame_info *next_frame, void **this_cache)
+sparc32_frame_base_address (struct frame_info *this_frame, void **this_cache)
 {
   struct sparc_frame_cache *cache =
-    sparc32_frame_cache (next_frame, this_cache);
+    sparc32_frame_cache (this_frame, this_cache);
 
   return cache->base;
 }
@@ -914,14 +1017,14 @@ static const struct frame_base sparc32_frame_base =
 };
 
 static struct frame_id
-sparc_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+sparc_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
   CORE_ADDR sp;
 
-  sp = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
+  sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
   if (sp & 1)
     sp += BIAS;
-  return frame_id_build (sp, frame_pc_unwind (next_frame));
+  return frame_id_build (sp, get_frame_pc (this_frame));
 }
 \f
 
@@ -1009,9 +1112,9 @@ sparc32_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 static enum return_value_convention
-sparc32_return_value (struct gdbarch *gdbarch, struct type *type,
-                     struct regcache *regcache, gdb_byte *readbuf,
-                     const gdb_byte *writebuf)
+sparc32_return_value (struct gdbarch *gdbarch, struct type *func_type,
+                     struct type *type, struct regcache *regcache,
+                     gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   /* The psABI says that "...every stack frame reserves the word at
      %fp+64.  If a function returns a structure, union, or
@@ -1052,9 +1155,9 @@ sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
 }
 
 static int
-sparc32_dwarf2_struct_return_p (struct frame_info *next_frame)
+sparc32_dwarf2_struct_return_p (struct frame_info *this_frame)
 {
-  CORE_ADDR pc = frame_unwind_address_in_block (next_frame);
+  CORE_ADDR pc = get_frame_address_in_block (this_frame);
   struct symbol *sym = find_pc_function (pc);
 
   if (sym)
@@ -1065,7 +1168,7 @@ sparc32_dwarf2_struct_return_p (struct frame_info *next_frame)
 static void
 sparc32_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
                               struct dwarf2_frame_state_reg *reg,
-                              struct frame_info *next_frame)
+                              struct frame_info *this_frame)
 {
   int off;
 
@@ -1084,7 +1187,7 @@ sparc32_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
     case SPARC32_NPC_REGNUM:
       reg->how = DWARF2_FRAME_REG_RA_OFFSET;
       off = 8;
-      if (sparc32_dwarf2_struct_return_p (next_frame))
+      if (sparc32_dwarf2_struct_return_p (this_frame))
        off += 4;
       if (regnum == SPARC32_NPC_REGNUM)
        off += 4;
@@ -1099,7 +1202,7 @@ sparc32_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
    software single-step mechanism.  */
 
 static CORE_ADDR
-sparc_analyze_control_transfer (struct gdbarch *arch,
+sparc_analyze_control_transfer (struct frame_info *frame,
                                CORE_ADDR pc, CORE_ADDR *npc)
 {
   unsigned long insn = sparc_fetch_instruction (pc);
@@ -1141,7 +1244,7 @@ sparc_analyze_control_transfer (struct gdbarch *arch,
   else if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3a)
     {
       /* Trap instruction (TRAP).  */
-      return gdbarch_tdep (arch)->step_trap (insn);
+      return gdbarch_tdep (get_frame_arch (frame))->step_trap (frame, insn);
     }
 
   /* FIXME: Handle DONE and RETRY instructions.  */
@@ -1174,81 +1277,47 @@ sparc_analyze_control_transfer (struct gdbarch *arch,
 }
 
 static CORE_ADDR
-sparc_step_trap (unsigned long insn)
+sparc_step_trap (struct frame_info *frame, unsigned long insn)
 {
   return 0;
 }
 
-void
-sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+int
+sparc_software_single_step (struct frame_info *frame)
 {
-  struct gdbarch *arch = current_gdbarch;
+  struct gdbarch *arch = get_frame_arch (frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
   CORE_ADDR npc, nnpc;
 
-  if (insert_breakpoints_p)
-    {
-      CORE_ADDR pc, orig_npc;
+  CORE_ADDR pc, orig_npc;
 
-      pc = sparc_address_from_register (tdep->pc_regnum);
-      orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);
+  pc = get_frame_register_unsigned (frame, tdep->pc_regnum);
+  orig_npc = npc = get_frame_register_unsigned (frame, tdep->npc_regnum);
 
-      /* Analyze the instruction at PC.  */
-      nnpc = sparc_analyze_control_transfer (arch, pc, &npc);
-      if (npc != 0)
-       insert_single_step_breakpoint (npc);
+  /* Analyze the instruction at PC.  */
+  nnpc = sparc_analyze_control_transfer (frame, pc, &npc);
+  if (npc != 0)
+    insert_single_step_breakpoint (npc);
 
-      if (nnpc != 0)
-       insert_single_step_breakpoint (nnpc);
-
-      /* Assert that we have set at least one breakpoint, and that
-        they're not set at the same spot - unless we're going
-        from here straight to NULL, i.e. a call or jump to 0.  */
-      gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
-      gdb_assert (nnpc != npc || orig_npc == 0);
-    }
-  else
-    remove_single_step_breakpoints ();
-}
+  if (nnpc != 0)
+    insert_single_step_breakpoint (nnpc);
 
-static void
-sparc_write_pc (CORE_ADDR pc, ptid_t ptid)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  /* Assert that we have set at least one breakpoint, and that
+     they're not set at the same spot - unless we're going
+     from here straight to NULL, i.e. a call or jump to 0.  */
+  gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
+  gdb_assert (nnpc != npc || orig_npc == 0);
 
-  write_register_pid (tdep->pc_regnum, pc, ptid);
-  write_register_pid (tdep->npc_regnum, pc + 4, ptid);
+  return 1;
 }
-\f
-/* Unglobalize NAME.  */
 
-char *
-sparc_stabs_unglobalize_name (char *name)
+static void
+sparc_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop,
-     SunPRO) convert file static variables into global values, a
-     process known as globalization.  In order to do this, the
-     compiler will create a unique prefix and prepend it to each file
-     static variable.  For static variables within a function, this
-     globalization prefix is followed by the function name (nested
-     static variables within a function are supposed to generate a
-     warning message, and are left alone).  The procedure is
-     documented in the Stabs Interface Manual, which is distrubuted
-     with the compilers, although version 4.0 of the manual seems to
-     be incorrect in some places, at least for SPARC.  The
-     globalization prefix is encoded into an N_OPT stab, with the form
-     "G=<prefix>".  The globalization prefix always seems to start
-     with a dollar sign '$'; a dot '.' is used as a seperator.  So we
-     simply strip everything up until the last dot.  */
-
-  if (name[0] == '$')
-    {
-      char *p = strrchr (name, '.');
-      if (p)
-       return p + 1;
-    }
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
 
-  return name;
+  regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
+  regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
 }
 \f
 
@@ -1333,7 +1402,7 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_software_single_step (gdbarch, sparc_software_single_step);
   set_gdbarch_write_pc (gdbarch, sparc_write_pc);
 
-  set_gdbarch_unwind_dummy_id (gdbarch, sparc_unwind_dummy_id);
+  set_gdbarch_dummy_id (gdbarch, sparc_dummy_id);
 
   set_gdbarch_unwind_pc (gdbarch, sparc_unwind_pc);
 
@@ -1347,7 +1416,7 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
-  frame_unwind_append_sniffer (gdbarch, sparc32_frame_sniffer);
+  frame_unwind_append_unwinder (gdbarch, &sparc32_frame_unwind);
 
   /* If we have register sets, enable the generic core file support.  */
   if (tdep->gregset)
@@ -1398,7 +1467,7 @@ sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum)
 
       /* Clear out the top half of the temporary buffer, and put the
         register value in the bottom half if we're in 64-bit mode.  */
-      if (gdbarch_ptr_bit (current_gdbarch) == 64)
+      if (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 64)
        {
          memset (buf, 0, 4);
          offset = 4;
@@ -1465,7 +1534,7 @@ sparc_collect_rwindow (const struct regcache *regcache,
       sp &= 0xffffffffUL;
 
       /* Only use the bottom half if we're in 64-bit mode.  */
-      if (gdbarch_ptr_bit (current_gdbarch) == 64)
+      if (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 64)
        offset = 4;
 
       for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
This page took 0.033008 seconds and 4 git commands to generate.