aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2005-03-25 16:51:40 +0000
committerMark Kettenis <kettenis@gnu.org>2005-03-25 16:51:40 +0000
commit8d5a9abc720e636a4547211695a6ceed1b21cb9d (patch)
tree156448df940b6cdf5fda9de156fca8bf438559a9 /gdb
parent4591cae21e057a132904d43e3e80fb15a7161fe8 (diff)
downloadgdb-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/ChangeLog9
-rw-r--r--gdb/dwarf2-frame.c49
-rw-r--r--gdb/dwarf2-frame.h3
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. */
};