* dwarf2-frame.c (dwarf2_frame_ops init_reg): Add "next_frame"
authorDavid S. Miller <davem@redhat.com>
Wed, 5 Apr 2006 20:01:19 +0000 (20:01 +0000)
committerDavid S. Miller <davem@redhat.com>
Wed, 5 Apr 2006 20:01:19 +0000 (20:01 +0000)
argument.
(dwarf2_frame_default_init_reg): Likewise.
(dwarf2_frame_set_init_reg): Update init_reg arg.
(dwarf2_frame_init_reg): Take "next_frame" and pass it to
ops->init_reg().
(dwarf2_frame_cache): Pass next_frame to dwarf2_frame_init_reg.
* dwarf2-frame.h (dwarf2-frame_set_init_reg): Update declaration.
* cris-tdep.c (cris_dwarf2_frame_init_reg): Add next_frame arg.
* s390-tdep.c (s390_dwarf2_frame_init_reg): Likewise.
* sh-tdep.c (sh_dwarf2_frame_init_reg): Likewise.
* sparc64-tdep.c (sparc64_dwarf2_frame_init_reg): Likewise.
* sparc-tdep.c (sparc32_struct_return_from_sym): New function.
(sparc32_frame_cache): Call it.
(sparc32_dwarf2_struct_return_p): New function.
(sparc_dwarf2_frame_init_reg): Use it to determine if the function
returns a structure and thus we have to indicate the return PC and
NPC are 4 bytes later than usual.

gdb/ChangeLog
gdb/cris-tdep.c
gdb/dwarf2-frame.c
gdb/dwarf2-frame.h
gdb/s390-tdep.c
gdb/sh-tdep.c
gdb/sparc-tdep.c
gdb/sparc64-tdep.c

index 88119f61fd2f0e7bcdb0ae2c19b066a1cfc5e8ce..18ce844e0269b8818642e56a755ac6ffbb29345e 100644 (file)
@@ -6,6 +6,24 @@
        * sparc-linux-tdep.c (sparc32_linux_sigframe_init): Pull register
        window out of the correct stack frame.
        * sparc64-linux-tdep.c (sparc64_linux_sigframe_init): Likewise.
+       * dwarf2-frame.c (dwarf2_frame_ops init_reg): Add "next_frame"
+       argument.
+       (dwarf2_frame_default_init_reg): Likewise.
+       (dwarf2_frame_set_init_reg): Update init_reg arg.
+       (dwarf2_frame_init_reg): Take "next_frame" and pass it to
+       ops->init_reg().
+       (dwarf2_frame_cache): Pass next_frame to dwarf2_frame_init_reg.
+       * dwarf2-frame.h (dwarf2-frame_set_init_reg): Update declaration.
+       * cris-tdep.c (cris_dwarf2_frame_init_reg): Add next_frame arg.
+       * s390-tdep.c (s390_dwarf2_frame_init_reg): Likewise.
+       * sh-tdep.c (sh_dwarf2_frame_init_reg): Likewise.
+       * sparc64-tdep.c (sparc64_dwarf2_frame_init_reg): Likewise.
+       * sparc-tdep.c (sparc32_struct_return_from_sym): New function.
+       (sparc32_frame_cache): Call it.
+       (sparc32_dwarf2_struct_return_p): New function.
+       (sparc_dwarf2_frame_init_reg): Use it to determine if the function
+       returns a structure and thus we have to indicate the return PC and
+       NPC are 4 bytes later than usual.
        
 2006-04-04  David S. Miller  <davem@davemloft.net>
 
index 0664318d654477c31d2ad4d6adb10f831a97c30d..4c81d6e9a5f8eb4b2b35e020d5749a84f2d19501 100644 (file)
@@ -1852,7 +1852,8 @@ cris_dwarf2_reg_to_regnum (int reg)
 
 static void
 cris_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
-                            struct dwarf2_frame_state_reg *reg)
+                            struct dwarf2_frame_state_reg *reg,
+                           struct frame_info *next_frame)
 {
   /* The return address column.  */
   if (regnum == PC_REGNUM)
index 668500d26c9863e64666ad0228ca171444d7e3cd..d479da2f5aa39d460ea7dffda24cfb220d9a43e2 100644 (file)
@@ -506,7 +506,8 @@ static struct gdbarch_data *dwarf2_frame_data;
 struct dwarf2_frame_ops
 {
   /* Pre-initialize the register state REG for register REGNUM.  */
-  void (*init_reg) (struct gdbarch *, int, struct dwarf2_frame_state_reg *);
+  void (*init_reg) (struct gdbarch *, int, struct dwarf2_frame_state_reg *,
+                   struct frame_info *);
 
   /* Check whether the frame preceding NEXT_FRAME will be a signal
      trampoline.  */
@@ -518,7 +519,8 @@ struct dwarf2_frame_ops
 
 static void
 dwarf2_frame_default_init_reg (struct gdbarch *gdbarch, int regnum,
-                              struct dwarf2_frame_state_reg *reg)
+                              struct dwarf2_frame_state_reg *reg,
+                              struct frame_info *next_frame)
 {
   /* If we have a register that acts as a program counter, mark it as
      a destination for the return address.  If we have a register that
@@ -570,7 +572,8 @@ dwarf2_frame_init (struct obstack *obstack)
 void
 dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
                           void (*init_reg) (struct gdbarch *, int,
-                                            struct dwarf2_frame_state_reg *))
+                                            struct dwarf2_frame_state_reg *,
+                                            struct frame_info *))
 {
   struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
 
@@ -581,11 +584,12 @@ dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
 
 static void
 dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
-                      struct dwarf2_frame_state_reg *reg)
+                      struct dwarf2_frame_state_reg *reg,
+                      struct frame_info *next_frame)
 {
   struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
 
-  ops->init_reg (gdbarch, regnum, reg);
+  ops->init_reg (gdbarch, regnum, reg, next_frame);
 }
 
 /* Set the architecture-specific signal trampoline recognition
@@ -713,7 +717,7 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
     int regnum;
 
     for (regnum = 0; regnum < num_regs; regnum++)
-      dwarf2_frame_init_reg (gdbarch, regnum, &cache->reg[regnum]);
+      dwarf2_frame_init_reg (gdbarch, regnum, &cache->reg[regnum], next_frame);
   }
 
   /* Go through the DWARF2 CFI generated table and save its register
index 3194604c95242a054c4ea0bd08ac0a0247979be5..a4ad586ad384d1f1a0549f63bf34c2c310998a32 100644 (file)
@@ -79,7 +79,8 @@ struct dwarf2_frame_state_reg
 
 extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
                                       void (*init_reg) (struct gdbarch *, int,
-                                            struct dwarf2_frame_state_reg *));
+                                            struct dwarf2_frame_state_reg *,
+                                            struct frame_info *));
 
 /* Set the architecture-specific signal trampoline recognition
    function for GDBARCH to SIGNAL_FRAME_P.  */
index dddef7a9f0218e4e9659724503d48ab97736e530..b7c700138c61c059e86fd55138d14385d8e9bff7 100644 (file)
@@ -2279,7 +2279,8 @@ s390_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 
 static void
 s390_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
-                            struct dwarf2_frame_state_reg *reg)
+                            struct dwarf2_frame_state_reg *reg,
+                           struct frame_info *next_frame)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
index 9f4e3dbd8a2c3a83e588cc6bad30ea461e6d5dac..2b4878e0cbaeebd7c9f447286d4183b2ff4a6508 100644 (file)
@@ -2123,7 +2123,8 @@ sh_sh2a_register_sim_regno (int nr)
 
 static void
 sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
-                          struct dwarf2_frame_state_reg *reg)
+                          struct dwarf2_frame_state_reg *reg,
+                         struct frame_info *next_frame)
 {
   /* Mark the PC as the destination for the return address.  */
   if (regnum == PC_REGNUM)
index 728ebadec21b21e660d30b6b8aa00d2f19c9f84e..e3b1ccfd43725a8e21a160847af2f9041ea28433 100644 (file)
@@ -680,6 +680,23 @@ sparc_frame_cache (struct frame_info *next_frame, void **this_cache)
   return cache;
 }
 
+static int
+sparc32_struct_return_from_sym (struct symbol *sym)
+{
+  struct type *type = check_typedef (SYMBOL_TYPE (sym));
+  enum type_code code = TYPE_CODE (type);
+
+  if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
+    {
+      type = check_typedef (TYPE_TARGET_TYPE (type));
+      if (sparc_structure_or_union_p (type)
+         || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
+       return 1;
+    }
+
+  return 0;
+}
+
 struct sparc_frame_cache *
 sparc32_frame_cache (struct frame_info *next_frame, void **this_cache)
 {
@@ -694,16 +711,7 @@ sparc32_frame_cache (struct frame_info *next_frame, void **this_cache)
   sym = find_pc_function (cache->pc);
   if (sym)
     {
-      struct type *type = check_typedef (SYMBOL_TYPE (sym));
-      enum type_code code = TYPE_CODE (type);
-
-      if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
-       {
-         type = check_typedef (TYPE_TARGET_TYPE (type));
-         if (sparc_structure_or_union_p (type)
-             || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
-           cache->struct_return_p = 1;
-       }
+      cache->struct_return_p = sparc32_struct_return_from_sym (sym);
     }
   else
     {
@@ -995,10 +1003,24 @@ sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
          || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16));
 }
 
+static int
+sparc32_dwarf2_struct_return_p (struct frame_info *next_frame)
+{
+  CORE_ADDR pc = frame_unwind_address_in_block (next_frame);
+  struct symbol *sym = find_pc_function (pc);
+
+  if (sym)
+    return sparc32_struct_return_from_sym (sym);
+  return 0;
+}
+
 static void
 sparc32_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
-                              struct dwarf2_frame_state_reg *reg)
+                              struct dwarf2_frame_state_reg *reg,
+                              struct frame_info *next_frame)
 {
+  int off;
+
   switch (regnum)
     {
     case SPARC_G0_REGNUM:
@@ -1011,12 +1033,14 @@ sparc32_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
       reg->how = DWARF2_FRAME_REG_CFA;
       break;
     case SPARC32_PC_REGNUM:
-      reg->how = DWARF2_FRAME_REG_RA_OFFSET;
-      reg->loc.offset = 8;
-      break;
     case SPARC32_NPC_REGNUM:
       reg->how = DWARF2_FRAME_REG_RA_OFFSET;
-      reg->loc.offset = 12;
+      off = 8;
+      if (sparc32_dwarf2_struct_return_p (next_frame))
+       off += 4;
+      if (regnum == SPARC32_NPC_REGNUM)
+       off += 4;
+      reg->loc.offset = off;
       break;
     }
 }
index d098bf96959d598ede2a2820a6422bdb0b2b2c74..ab6dfabc0d4712592cfd64dd4ba60873afe01f76 100644 (file)
@@ -1106,7 +1106,8 @@ sparc64_return_value (struct gdbarch *gdbarch, struct type *type,
 
 static void
 sparc64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
-                              struct dwarf2_frame_state_reg *reg)
+                              struct dwarf2_frame_state_reg *reg,
+                              struct frame_info *next_frame)
 {
   switch (regnum)
     {