diff options
author | Mark Kettenis <kettenis@gnu.org> | 2005-03-25 16:51:40 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2005-03-25 16:51:40 +0000 |
commit | 8d5a9abc720e636a4547211695a6ceed1b21cb9d (patch) | |
tree | 156448df940b6cdf5fda9de156fca8bf438559a9 /gdb | |
parent | 4591cae21e057a132904d43e3e80fb15a7161fe8 (diff) | |
download | gdb-8d5a9abc720e636a4547211695a6ceed1b21cb9d.zip gdb-8d5a9abc720e636a4547211695a6ceed1b21cb9d.tar.gz gdb-8d5a9abc720e636a4547211695a6ceed1b21cb9d.tar.bz2 |
* 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.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/dwarf2-frame.c | 49 | ||||
-rw-r--r-- | gdb/dwarf2-frame.h | 3 |
3 files changed, 52 insertions, 9 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 920928f..03d5115 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2005-03-25 Mark Kettenis <kettenis@gnu.org> + + * 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 <hunt@redhat.com> * configure.ac: Remove -fwritable-strings from CFLAGS. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index cedeaa1..7b46c78 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 5191c0e..7f951e7 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. */ }; |