From aff37fc18f86e6a07749f9243124fb126b3330c2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 5 Apr 2006 20:01:19 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 18 ++++++++++++++++ gdb/cris-tdep.c | 3 ++- gdb/dwarf2-frame.c | 16 ++++++++------ gdb/dwarf2-frame.h | 3 ++- gdb/s390-tdep.c | 3 ++- gdb/sh-tdep.c | 3 ++- gdb/sparc-tdep.c | 54 +++++++++++++++++++++++++++++++++------------- gdb/sparc64-tdep.c | 3 ++- 8 files changed, 77 insertions(+), 26 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 88119f61fd..18ce844e02 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 diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c index 0664318d65..4c81d6e9a5 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 668500d26c..d479da2f5a 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 3194604c95..a4ad586ad3 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 dddef7a9f0..b7c700138c 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 9f4e3dbd8a..2b4878e0cb 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 728ebadec2..e3b1ccfd43 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 d098bf9695..ab6dfabc0d 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) { -- 2.34.1