aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@redhat.com>2006-04-05 20:01:19 +0000
committerDavid S. Miller <davem@redhat.com>2006-04-05 20:01:19 +0000
commitaff37fc18f86e6a07749f9243124fb126b3330c2 (patch)
treecdde0f3fd196ff430e487e9b2882eea9b1d5ef15
parent0781db9f1005afbda29c49f5cb3ef85d7c799db0 (diff)
downloadgdb-aff37fc18f86e6a07749f9243124fb126b3330c2.zip
gdb-aff37fc18f86e6a07749f9243124fb126b3330c2.tar.gz
gdb-aff37fc18f86e6a07749f9243124fb126b3330c2.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog18
-rw-r--r--gdb/cris-tdep.c3
-rw-r--r--gdb/dwarf2-frame.c16
-rw-r--r--gdb/dwarf2-frame.h3
-rw-r--r--gdb/s390-tdep.c3
-rw-r--r--gdb/sh-tdep.c3
-rw-r--r--gdb/sparc-tdep.c54
-rw-r--r--gdb/sparc64-tdep.c3
8 files changed, 77 insertions, 26 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 88119f6..18ce844 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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>
diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
index 0664318..4c81d6e 100644
--- a/gdb/cris-tdep.c
+++ b/gdb/cris-tdep.c
@@ -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)
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 668500d..d479da2 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -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
diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h
index 3194604..a4ad586 100644
--- a/gdb/dwarf2-frame.h
+++ b/gdb/dwarf2-frame.h
@@ -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. */
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index dddef7a..b7c7001 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -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);
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 9f4e3db..2b4878e 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -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)
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 728ebad..e3b1ccf 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -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;
}
}
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index d098bf9..ab6dfab 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -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)
{