* configure.tgt (*-*-vxworks): Match vxworks* instead.
[binutils-gdb.git] / gdb / sparc-tdep.c
index e17e0a716e426e02fb13b065b482cff62a0d56ca..1468943d53581760da21a807f7385ca04b03e144 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for SPARC.
 
-   Copyright 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -93,7 +93,7 @@ struct regset;
 unsigned long
 sparc_fetch_instruction (CORE_ADDR pc)
 {
-  unsigned char buf[4];
+  gdb_byte buf[4];
   unsigned long insn;
   int i;
 
@@ -154,7 +154,7 @@ ULONGEST
 sparc_fetch_wcookie (void)
 {
   struct target_ops *ops = &current_target;
-  char buf[8];
+  gdb_byte buf[8];
   int len;
 
   len = target_read_partial (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8);
@@ -318,25 +318,25 @@ sparc32_register_type (struct gdbarch *gdbarch, int regnum)
 static void
 sparc32_pseudo_register_read (struct gdbarch *gdbarch,
                              struct regcache *regcache,
-                             int regnum, void *buf)
+                             int regnum, gdb_byte *buf)
 {
   gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
 
   regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
   regcache_raw_read (regcache, regnum, buf);
-  regcache_raw_read (regcache, regnum + 1, ((char *)buf) + 4);
+  regcache_raw_read (regcache, regnum + 1, buf + 4);
 }
 
 static void
 sparc32_pseudo_register_write (struct gdbarch *gdbarch,
                               struct regcache *regcache,
-                              int regnum, const void *buf)
+                              int regnum, const gdb_byte *buf)
 {
   gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
 
   regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
   regcache_raw_write (regcache, regnum, buf);
-  regcache_raw_write (regcache, regnum + 1, ((const char *)buf) + 4);
+  regcache_raw_write (regcache, regnum + 1, buf + 4);
 }
 \f
 
@@ -352,7 +352,7 @@ sparc32_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
 
   if (using_struct_return (value_type, using_gcc))
     {
-      char buf[4];
+      gdb_byte buf[4];
 
       /* This is an UNIMP instruction.  */
       store_unsigned_integer (buf, 4, TYPE_LENGTH (value_type) & 0x1fff);
@@ -388,7 +388,7 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
              correct, and wasting a few bytes shouldn't be a problem.  */
          sp &= ~0x7;
 
-         write_memory (sp, VALUE_CONTENTS (args[i]), len);
+         write_memory (sp, value_contents (args[i]), len);
          args[i] = value_from_pointer (lookup_pointer_type (type), sp);
          num_elements++;
        }
@@ -423,7 +423,7 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
 
   for (i = 0; i < nargs; i++)
     {
-      char *valbuf = VALUE_CONTENTS (args[i]);
+      const bfd_byte *valbuf = value_contents (args[i]);
       struct type *type = value_type (args[i]);
       int len = TYPE_LENGTH (type);
 
@@ -447,7 +447,7 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
 
   if (struct_return)
     {
-      char buf[4];
+      gdb_byte buf[4];
 
       store_unsigned_integer (buf, 4, struct_addr);
       write_memory (sp, buf, 4);
@@ -490,10 +490,10 @@ sparc32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
    *LEN and optionally adjust *PC to point to the correct memory
    location for inserting the breakpoint.  */
    
-static const unsigned char *
+static const gdb_byte *
 sparc_breakpoint_from_pc (CORE_ADDR *pc, int *len)
 {
-  static unsigned char break_insn[] = { 0x91, 0xd0, 0x20, 0x01 };
+  static const gdb_byte break_insn[] = { 0x91, 0xd0, 0x20, 0x01 };
 
   *len = sizeof (break_insn);
   return break_insn;
@@ -673,6 +673,9 @@ sparc_frame_cache (struct frame_info *next_frame, void **this_cache)
        frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM);
     }
 
+  if (cache->base & 1)
+    cache->base += BIAS;
+
   return cache;
 }
 
@@ -738,7 +741,7 @@ 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, void *valuep)
+                            int *realnump, gdb_byte *valuep)
 {
   struct sparc_frame_cache *cache =
     sparc32_frame_cache (next_frame, this_cache);
@@ -859,6 +862,8 @@ sparc_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
   CORE_ADDR sp;
 
   sp = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
+  if (sp & 1)
+    sp += BIAS;
   return frame_id_build (sp, frame_pc_unwind (next_frame));
 }
 \f
@@ -868,10 +873,10 @@ sparc_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 
 static void
 sparc32_extract_return_value (struct type *type, struct regcache *regcache,
-                             void *valbuf)
+                             gdb_byte *valbuf)
 {
   int len = TYPE_LENGTH (type);
-  char buf[8];
+  gdb_byte buf[8];
 
   gdb_assert (!sparc_structure_or_union_p (type));
   gdb_assert (!(sparc_floating_p (type) && len == 16));
@@ -910,10 +915,10 @@ sparc32_extract_return_value (struct type *type, struct regcache *regcache,
 
 static void
 sparc32_store_return_value (struct type *type, struct regcache *regcache,
-                           const void *valbuf)
+                           const gdb_byte *valbuf)
 {
   int len = TYPE_LENGTH (type);
-  char buf[8];
+  gdb_byte buf[8];
 
   gdb_assert (!sparc_structure_or_union_p (type));
   gdb_assert (!(sparc_floating_p (type) && len == 16));
@@ -948,8 +953,8 @@ 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, void *readbuf,
-                     const void *writebuf)
+                     struct regcache *regcache, gdb_byte *readbuf,
+                     const gdb_byte *writebuf)
 {
   if (sparc_structure_or_union_p (type)
       || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
@@ -1077,7 +1082,7 @@ sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   static CORE_ADDR npc, nnpc;
-  static char npc_save[4], nnpc_save[4];
+  static gdb_byte npc_save[4], nnpc_save[4];
 
   if (insert_breakpoints_p)
     {
@@ -1254,7 +1259,7 @@ void
 sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum)
 {
   int offset = 0;
-  char buf[8];
+  gdb_byte buf[8];
   int i;
 
   if (sp & 1)
@@ -1267,6 +1272,16 @@ sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum)
          if (regnum == i || regnum == -1)
            {
              target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8);
+
+             /* Handle StackGhost.  */
+             if (i == SPARC_I7_REGNUM)
+               {
+                 ULONGEST wcookie = sparc_fetch_wcookie ();
+                 ULONGEST i7 = extract_unsigned_integer (buf + offset, 8);
+
+                 store_unsigned_integer (buf + offset, 8, i7 ^ wcookie);
+               }
+
              regcache_raw_supply (regcache, i, buf);
            }
        }
@@ -1312,7 +1327,7 @@ sparc_collect_rwindow (const struct regcache *regcache,
                       CORE_ADDR sp, int regnum)
 {
   int offset = 0;
-  char buf[8];
+  gdb_byte buf[8];
   int i;
 
   if (sp & 1)
@@ -1325,6 +1340,16 @@ sparc_collect_rwindow (const struct regcache *regcache,
          if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i)
            {
              regcache_raw_collect (regcache, i, buf);
+
+             /* Handle StackGhost.  */
+             if (i == SPARC_I7_REGNUM)
+               {
+                 ULONGEST wcookie = sparc_fetch_wcookie ();
+                 ULONGEST i7 = extract_unsigned_integer (buf + offset, 8);
+
+                 store_unsigned_integer (buf, 8, i7 ^ wcookie);
+               }
+
              target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8);
            }
        }
@@ -1368,7 +1393,7 @@ sparc32_supply_gregset (const struct sparc_gregset *gregset,
                        struct regcache *regcache,
                        int regnum, const void *gregs)
 {
-  const char *regs = gregs;
+  const gdb_byte *regs = gregs;
   int i;
 
   if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
@@ -1432,7 +1457,7 @@ sparc32_collect_gregset (const struct sparc_gregset *gregset,
                         const struct regcache *regcache,
                         int regnum, void *gregs)
 {
-  char *regs = gregs;
+  gdb_byte *regs = gregs;
   int i;
 
   if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
@@ -1486,7 +1511,7 @@ void
 sparc32_supply_fpregset (struct regcache *regcache,
                         int regnum, const void *fpregs)
 {
-  const char *regs = fpregs;
+  const gdb_byte *regs = fpregs;
   int i;
 
   for (i = 0; i < 32; i++)
@@ -1503,7 +1528,7 @@ void
 sparc32_collect_fpregset (const struct regcache *regcache,
                          int regnum, void *fpregs)
 {
-  char *regs = fpregs;
+  gdb_byte *regs = fpregs;
   int i;
 
   for (i = 0; i < 32; i++)