From 8d5a9abc720e636a4547211695a6ceed1b21cb9d Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Fri, 25 Mar 2005 16:51:40 +0000 Subject: [PATCH] * dwarf2-frame.h: Update copyrigh year. (enum dwarf2_frame_reg_rule): Add DWARF2_FRAME_REG_RA_OFFSET. * dwarf2-frame.c: Update copyright year. (struct dwarf2_frame_cache): Add member `retaddr_reg'. (dwarf2_frame_cache): Deal with DWARF2_FRAME_REG_RA_OFFSET. (dwarf2_frame_prev_register): Handle DWARF2_FRAME_REG_RA_OFFSET. --- gdb/ChangeLog | 9 +++++++++ gdb/dwarf2-frame.c | 49 ++++++++++++++++++++++++++++++++++++++-------- gdb/dwarf2-frame.h | 3 ++- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 920928f62c3..03d511504aa 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2005-03-25 Mark Kettenis + + * dwarf2-frame.h: Update copyrigh year. + (enum dwarf2_frame_reg_rule): Add DWARF2_FRAME_REG_RA_OFFSET. + * dwarf2-frame.c: Update copyright year. + (struct dwarf2_frame_cache): Add member `retaddr_reg'. + (dwarf2_frame_cache): Deal with DWARF2_FRAME_REG_RA_OFFSET. + (dwarf2_frame_prev_register): Handle DWARF2_FRAME_REG_RA_OFFSET. + 2005-03-23 Martin Hunt * configure.ac: Remove -fwritable-strings from CFLAGS. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index cedeaa1f547..7b46c78dbaa 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -1,6 +1,6 @@ /* Frame unwinder for frames with DWARF Call Frame Information. - Copyright 2003, 2004 Free Software Foundation, Inc. + Copyright 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Mark Kettenis. @@ -588,6 +588,9 @@ struct dwarf2_frame_cache /* Saved registers, indexed by GDB register number, not by DWARF register number. */ struct dwarf2_frame_state_reg *reg; + + /* Return address register. */ + struct dwarf2_frame_state_reg retaddr_reg; }; static struct dwarf2_frame_cache * @@ -717,13 +720,15 @@ incomplete CFI data; unspecified registers (e.g., %s) at 0x%s"), } } - /* Eliminate any DWARF2_FRAME_REG_RA rules. */ + /* Eliminate any DWARF2_FRAME_REG_RA rules, and save the information + we need for evaluating DWARF2_FRAME_REG_RA_OFFSET rules. */ { int regnum; for (regnum = 0; regnum < num_regs; regnum++) { - if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA) + if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA + || cache->reg[regnum].how == DWARF2_FRAME_REG_RA_OFFSET) { struct dwarf2_frame_state_reg *retaddr_reg = &fs->regs.reg[fs->retaddr_column]; @@ -733,16 +738,29 @@ incomplete CFI data; unspecified registers (e.g., %s) at 0x%s"), what GCC does on some targets. It turns out that GCC assumes that the return address can be found in the register corresponding to the return address column. - Incidentally, that's how should treat a return address - column specifying "same value" too. */ + Incidentally, that's how we should treat a return + address column specifying "same value" too. */ if (fs->retaddr_column < fs->regs.num_regs && retaddr_reg->how != DWARF2_FRAME_REG_UNSPECIFIED && retaddr_reg->how != DWARF2_FRAME_REG_SAME_VALUE) - cache->reg[regnum] = *retaddr_reg; + { + if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA) + cache->reg[regnum] = *retaddr_reg; + else + cache->retaddr_reg = *retaddr_reg; + } else { - cache->reg[regnum].loc.reg = fs->retaddr_column; - cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG; + if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA) + { + cache->reg[regnum].loc.reg = fs->retaddr_column; + cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG; + } + else + { + cache->retaddr_reg.loc.reg = fs->retaddr_column; + cache->retaddr_reg.how = DWARF2_FRAME_REG_SAVED_REG; + } } } } @@ -864,6 +882,21 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache, } break; + case DWARF2_FRAME_REG_RA_OFFSET: + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + CORE_ADDR pc = cache->reg[regnum].loc.offset; + + regnum = DWARF2_REG_TO_REGNUM (cache->retaddr_reg.loc.reg); + pc += frame_unwind_register_unsigned (next_frame, regnum); + store_typed_address (valuep, builtin_type_void_func_ptr, pc); + } + break; + default: internal_error (__FILE__, __LINE__, _("Unknown register rule.")); } diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h index 5191c0e8d49..7f951e7c6da 100644 --- a/gdb/dwarf2-frame.h +++ b/gdb/dwarf2-frame.h @@ -1,6 +1,6 @@ /* Frame unwinder for frames with DWARF Call Frame Information. - Copyright 2003, 2004 Free Software Foundation, Inc. + Copyright 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Mark Kettenis. @@ -54,6 +54,7 @@ enum dwarf2_frame_reg_rule /* These aren't defined by the DWARF2 CFI specification, but are used internally by GDB. */ DWARF2_FRAME_REG_RA, /* Return Address. */ + DWARF2_FRAME_REG_RA_OFFSET, /* Return Address with offset. */ DWARF2_FRAME_REG_CFA /* Call Frame Address. */ }; -- 2.30.2